mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-30 12:10:03 +02:00
Merge pull request #632 from EmilieNumworks/exam_mode_boricj
LED blinking with timer (steady blinking + blinking in stand-by mode)
This commit is contained in:
@@ -22,7 +22,6 @@ app_objs += $(addprefix apps/,\
|
||||
exam_pop_up_controller.o\
|
||||
global_preferences.o\
|
||||
i18n.o\
|
||||
led_timer.o\
|
||||
lock_view.o\
|
||||
main.o\
|
||||
math_toolbox.o\
|
||||
|
||||
@@ -16,7 +16,6 @@ AppsContainer::AppsContainer() :
|
||||
m_variableBoxController(&m_globalContext),
|
||||
m_examPopUpController(this),
|
||||
m_updateController(),
|
||||
m_ledTimer(LedTimer()),
|
||||
m_batteryTimer(BatteryTimer(this)),
|
||||
m_suspendTimer(SuspendTimer(this)),
|
||||
m_backlightDimmingTimer(),
|
||||
@@ -230,11 +229,11 @@ Window * AppsContainer::window() {
|
||||
}
|
||||
|
||||
int AppsContainer::numberOfContainerTimers() {
|
||||
return 3+(GlobalPreferences::sharedGlobalPreferences()->examMode() == GlobalPreferences::ExamMode::Activate);
|
||||
return 3;
|
||||
}
|
||||
|
||||
Timer * AppsContainer::containerTimerAtIndex(int i) {
|
||||
Timer * timers[4] = {&m_batteryTimer, &m_suspendTimer, &m_backlightDimmingTimer, &m_ledTimer};
|
||||
Timer * timers[3] = {&m_batteryTimer, &m_suspendTimer, &m_backlightDimmingTimer};
|
||||
return timers[i];
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "variable_box_controller.h"
|
||||
#include "exam_pop_up_controller.h"
|
||||
#include "exam_pop_up_controller_delegate.h"
|
||||
#include "led_timer.h"
|
||||
#include "battery_timer.h"
|
||||
#include "suspend_timer.h"
|
||||
#include "backlight_dimming_timer.h"
|
||||
@@ -69,7 +68,6 @@ private:
|
||||
VariableBoxController m_variableBoxController;
|
||||
ExamPopUpController m_examPopUpController;
|
||||
OnBoarding::UpdateController m_updateController;
|
||||
LedTimer m_ledTimer;
|
||||
BatteryTimer m_batteryTimer;
|
||||
SuspendTimer m_suspendTimer;
|
||||
BacklightDimmingTimer m_backlightDimmingTimer;
|
||||
|
||||
@@ -58,6 +58,8 @@ ExamPopUpController::ContentView::ContentView(Responder * parentResponder) :
|
||||
AppsContainer * container = (AppsContainer *)controller->app()->container();
|
||||
if (controller->isActivatingExamMode()) {
|
||||
container->reset();
|
||||
Ion::LED::setColor(KDColorRed);
|
||||
Ion::LED::setBlinking(1.0f, 0.1f);
|
||||
} else {
|
||||
Ion::LED::setColor(KDColorBlack);
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#include "led_timer.h"
|
||||
|
||||
LedTimer::LedTimer() :
|
||||
Timer(1),
|
||||
m_on(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool LedTimer::fire() {
|
||||
m_on = !m_on;
|
||||
KDColor ledColor = m_on ? KDColorRed : KDColorBlack;
|
||||
Ion::LED::setColor(ledColor);
|
||||
return false;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#ifndef APPS_LED_TIMER_H
|
||||
#define APPS_LED_TIMER_H
|
||||
|
||||
#include <escher.h>
|
||||
|
||||
class LedTimer : public Timer {
|
||||
public:
|
||||
LedTimer();
|
||||
private:
|
||||
bool fire() override;
|
||||
bool m_on;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
namespace Ion {
|
||||
namespace LED {
|
||||
|
||||
KDColor getColor();
|
||||
void setColor(KDColor c);
|
||||
void setBlinking(float period, float dutyCycle);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ void initPeripherals() {
|
||||
SWD::Device::init();
|
||||
}
|
||||
|
||||
void shutdownPeripherals() {
|
||||
void shutdownPeripherals(bool keepLEDAwake) {
|
||||
SWD::Device::shutdown();
|
||||
Console::Device::shutdown();
|
||||
#if USE_SD_CARD
|
||||
@@ -177,7 +177,9 @@ void shutdownPeripherals() {
|
||||
#endif
|
||||
USB::Device::shutdown();
|
||||
Battery::Device::shutdown();
|
||||
LED::Device::shutdown();
|
||||
if (!keepLEDAwake) {
|
||||
LED::Device::shutdown();
|
||||
}
|
||||
Keyboard::Device::shutdown();
|
||||
Backlight::Device::shutdown();
|
||||
Display::Device::shutdown();
|
||||
@@ -265,7 +267,7 @@ void initClocks() {
|
||||
RCC.AHB3ENR()->setFSMCEN(true);
|
||||
|
||||
// APB1 bus
|
||||
// We're using TIM3
|
||||
// We're using TIM3 for the LEDs
|
||||
RCC.APB1ENR()->setTIM3EN(true);
|
||||
RCC.APB1ENR()->setPWREN(true);
|
||||
|
||||
@@ -279,15 +281,33 @@ void initClocks() {
|
||||
RCC.APB2ENR()->set(apb2enr);
|
||||
}
|
||||
|
||||
void shutdownClocks() {
|
||||
void shutdownClocks(bool keepLEDAwake) {
|
||||
// APB2 bus
|
||||
RCC.APB2ENR()->set(0x00008000); // Reset value
|
||||
|
||||
// AHB1
|
||||
RCC.APB1ENR()->set(0x00000400);
|
||||
if (keepLEDAwake) {
|
||||
/* TODO: enter sleep mode even if the LED is used and enable LED in low
|
||||
* power mode. */
|
||||
// Keep the LED going: peripheral clock enable in low power mode register
|
||||
/*RCC.APB1LPENR()->setTIM3LPEN(true);
|
||||
RCC.AHB1LPENR()->setGPIOBLPEN(true);
|
||||
RCC.AHB1LPENR()->setGPIOCLPEN(true);*/
|
||||
|
||||
// AHB1 bus
|
||||
RCC.AHB1ENR()->set(0); // Reset value
|
||||
// APB1
|
||||
class RCC::APB1ENR apb1enr(0x00000400);
|
||||
apb1enr.setTIM3EN(true);
|
||||
RCC.APB1ENR()->set(apb1enr);
|
||||
// AHB1 bus
|
||||
class RCC::AHB1ENR ahb1enr(0); // Reset value
|
||||
ahb1enr.setGPIOBEN(true);
|
||||
ahb1enr.setGPIOCEN(true);
|
||||
RCC.AHB1ENR()->set(ahb1enr);
|
||||
} else {
|
||||
// APB1
|
||||
RCC.APB1ENR()->set(0x00000400);
|
||||
// AHB1 bus
|
||||
RCC.AHB1ENR()->set(0); // Reset value
|
||||
}
|
||||
|
||||
RCC.AHB3ENR()->setFSMCEN(false);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
namespace Ion {
|
||||
namespace Device {
|
||||
|
||||
constexpr int SYSBUS_FREQ = 96*1000*1000;
|
||||
|
||||
void init();
|
||||
void shutdown();
|
||||
|
||||
@@ -12,9 +14,9 @@ void coreReset();
|
||||
void jumpReset();
|
||||
|
||||
void initPeripherals();
|
||||
void shutdownPeripherals();
|
||||
void shutdownPeripherals(bool keepLEDAwake = false);
|
||||
void initClocks();
|
||||
void shutdownClocks();
|
||||
void shutdownClocks(bool keepLEDAwake = false);
|
||||
|
||||
/* The serial number is 96 bits long. That's equal to 16 digits in base 64. We
|
||||
* expose a convenient "copySerialNumber" routine which can be called without
|
||||
|
||||
@@ -1,16 +1,55 @@
|
||||
#include <ion/led.h>
|
||||
#include <ion/display.h>
|
||||
#include "device.h"
|
||||
#include "led.h"
|
||||
#include "regs/regs.h"
|
||||
|
||||
// Public Ion::LED methods
|
||||
|
||||
void Ion::LED::setColor(KDColor c) {
|
||||
TIM3.CCR2()->set(Device::dutyCycleForUInt8(c.red()));
|
||||
TIM3.CCR3()->set(Device::dutyCycleForUInt8(c.blue()));
|
||||
TIM3.CCR4()->set(Device::dutyCycleForUInt8(c.green()));
|
||||
static KDColor sLedColor = KDColorBlack;
|
||||
|
||||
KDColor Ion::LED::getColor() {
|
||||
return sLedColor;
|
||||
}
|
||||
|
||||
void Ion::LED::setColor(KDColor c) {
|
||||
sLedColor = c;
|
||||
|
||||
/* Active RGB colors */
|
||||
Ion::LED::Device::setColorStatus(Ion::LED::Device::Color::RED, true);
|
||||
Ion::LED::Device::setColorStatus(Ion::LED::Device::Color::GREEN, true);
|
||||
Ion::LED::Device::setColorStatus(Ion::LED::Device::Color::BLUE, true);
|
||||
|
||||
/* Set the PWM duty cycles to display the right color */
|
||||
constexpr float maxColorValue = (float)((1 << 8) -1);
|
||||
Device::setPeriodAndDutyCycles(Device::Mode::PWM, c.red()/maxColorValue, c.green()/maxColorValue, c.blue()/maxColorValue);
|
||||
}
|
||||
|
||||
void Ion::LED::setBlinking(float period, float dutyCycle) {
|
||||
/* We want to use the PWM at a slow rate to display a seeable blink.
|
||||
* Consequently, we do not use PWM to display the right color anymore.
|
||||
* Instead we 'project the color on 3 bits' : RED LED is active or not etc. */
|
||||
Ion::LED::Device::setColorStatus(Ion::LED::Device::Color::RED, sLedColor.red() > 0);
|
||||
Ion::LED::Device::setColorStatus(Ion::LED::Device::Color::GREEN, sLedColor.green() > 0);
|
||||
Ion::LED::Device::setColorStatus(Ion::LED::Device::Color::BLUE, sLedColor.blue() > 0);
|
||||
|
||||
Device::setPeriodAndDutyCycles(Device::Mode::BLINK, dutyCycle, dutyCycle, dutyCycle, period);
|
||||
}
|
||||
|
||||
/*void Ion::LED::setCharging(bool isPluggedIn, bool isCharging) {
|
||||
if (!isPluggedIn) {
|
||||
Ion::LED::setColor(KDColorBlack);
|
||||
}
|
||||
else {
|
||||
if (isCharging) {
|
||||
Ion::LED::setColor(KDColorRed);
|
||||
}
|
||||
else {
|
||||
Ion::LED::setColor(KDColorGreen);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
// Private Ion::Device::LED methods
|
||||
|
||||
namespace Ion {
|
||||
@@ -45,23 +84,6 @@ void shutdownGPIO() {
|
||||
}
|
||||
|
||||
void initTimer() {
|
||||
/* Let's set the prescaler to 1. Increasing the prescaler would slow down the
|
||||
* modulation, which can be useful when debugging. */
|
||||
TIM3.PSC()->set(1);
|
||||
|
||||
/* Pulse width modulation mode allows you to generate a signal with a
|
||||
* frequency determined by the value of the TIMx_ARR register and a duty cycle
|
||||
* determined by the value of the TIMx_CCRx register. */
|
||||
TIM3.ARR()->set(PWMPeriod);
|
||||
TIM3.CCR2()->set(0);
|
||||
TIM3.CCR3()->set(0);
|
||||
TIM3.CCR4()->set(0);
|
||||
|
||||
// Set Channels 2-4 as outputs, PWM mode 1
|
||||
TIM3.CCMR()->setOC2M(TIM::CCMR::OCM::PWM1);
|
||||
TIM3.CCMR()->setOC3M(TIM::CCMR::OCM::PWM1);
|
||||
TIM3.CCMR()->setOC4M(TIM::CCMR::OCM::PWM1);
|
||||
|
||||
// Output preload enable for channels 2-4
|
||||
TIM3.CCMR()->setOC2PE(true);
|
||||
TIM3.CCMR()->setOC3PE(true);
|
||||
@@ -81,12 +103,53 @@ void initTimer() {
|
||||
}
|
||||
|
||||
void shutdownTimer() {
|
||||
TIM3.CCMR()->setOC2M(TIM::CCMR::OCM::ForceInactive);
|
||||
TIM3.CCMR()->setOC3M(TIM::CCMR::OCM::ForceInactive);
|
||||
TIM3.CCMR()->setOC4M(TIM::CCMR::OCM::ForceInactive);
|
||||
setColorStatus(Ion::LED::Device::Color::RED, false);
|
||||
setColorStatus(Ion::LED::Device::Color::GREEN, false);
|
||||
setColorStatus(Ion::LED::Device::Color::BLUE, false);
|
||||
}
|
||||
|
||||
void enforceState(bool red, bool green, bool blue) {
|
||||
/* Pulse width modulation mode allows you to generate a signal with a
|
||||
* frequency determined by the value of the TIMx_ARR register and a duty cycle
|
||||
* determined by the value of the TIMx_CCRx register. */
|
||||
|
||||
void setPeriodAndDutyCycles(Mode mode, float dutyCycleRed, float dutyCycleGreen, float dutyCycleBlue, float period) {
|
||||
constexpr int TIM3_FREQ = 4*1000;
|
||||
switch (mode) {
|
||||
case Mode::PWM:
|
||||
/* Let's set the prescaler to 1. Increasing the prescaler would slow down the
|
||||
* modulation, which can be useful when debugging. */
|
||||
TIM3.PSC()->set(1);
|
||||
TIM3.ARR()->set(PWMPeriod);
|
||||
period = PWMPeriod;
|
||||
break;
|
||||
case Mode::BLINK:
|
||||
/* We still want to do PWM, but at a rate slow enough to blink. */
|
||||
TIM3.PSC()->set(Ion::Device::SYSBUS_FREQ / TIM3_FREQ);
|
||||
TIM3.ARR()->set(period * TIM3_FREQ);
|
||||
period *= TIM3_FREQ; // as we pre-scaled, we update the period
|
||||
break;
|
||||
}
|
||||
|
||||
TIM3.CCR2()->set(dutyCycleRed*period);
|
||||
TIM3.CCR3()->set(dutyCycleBlue*period);
|
||||
TIM3.CCR4()->set(dutyCycleGreen*period);
|
||||
}
|
||||
|
||||
void setColorStatus(Color color, bool enable) {
|
||||
switch (color) {
|
||||
case Ion::LED::Device::Color::RED:
|
||||
TIM3.CCMR()->setOC2M(enable ? TIM<Register16>::CCMR::OCM::PWM1 : TIM<Register16>::CCMR::OCM::ForceInactive);
|
||||
break;
|
||||
case Ion::LED::Device::Color::GREEN:
|
||||
TIM3.CCMR()->setOC4M(enable ? TIM<Register16>::CCMR::OCM::PWM1 : TIM<Register16>::CCMR::OCM::ForceInactive);
|
||||
break;
|
||||
case Ion::LED::Device::Color::BLUE:
|
||||
TIM3.CCMR()->setOC3M(enable ? TIM<Register16>::CCMR::OCM::PWM1 : TIM<Register16>::CCMR::OCM::ForceInactive);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*void enforceState(bool red, bool green, bool blue) {
|
||||
bool states[3] = {red, green, blue};
|
||||
for (int i=0; i<3; i++) {
|
||||
GPIOPin p = RGBPins[i];
|
||||
@@ -98,7 +161,7 @@ void enforceState(bool red, bool green, bool blue) {
|
||||
p.group().PUPDR()->setPull(p.pin(), GPIO::PUPDR::Pull::None);
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,10 +14,23 @@ namespace Device {
|
||||
* PC7 | LED red | Alternate Function 2 | TIM3_CH2
|
||||
*/
|
||||
|
||||
enum Mode {
|
||||
PWM,
|
||||
BLINK
|
||||
};
|
||||
|
||||
enum Color {
|
||||
RED,
|
||||
GREEN,
|
||||
BLUE
|
||||
};
|
||||
|
||||
void init();
|
||||
void shutdown();
|
||||
void setPeriodAndDutyCycles(Mode mode, float dutyCycleRed, float dutyCycleGreen, float dutyCycleBlue, float period = 0.0f);
|
||||
void setColorStatus(Color color, bool enable);
|
||||
/* This call bypasses the timer, and immediately enforces a given LED state. */
|
||||
void enforceState(bool red, bool green, bool blue);
|
||||
//void enforceState(bool red, bool green, bool blue);
|
||||
|
||||
void initGPIO();
|
||||
void shutdownGPIO();
|
||||
@@ -31,11 +44,6 @@ constexpr static GPIOPin RGBPins[] = {
|
||||
|
||||
constexpr uint16_t PWMPeriod = 40000;
|
||||
|
||||
inline uint16_t dutyCycleForUInt8(uint8_t value) {
|
||||
/* This function is a linear function from colors [0->255] to duty cycles [0->PWMPeriod].*/
|
||||
return ((uint32_t)value)*(PWMPeriod/255);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "regs/regs.h"
|
||||
|
||||
void Ion::Power::suspend(bool checkIfPowerKeyReleased) {
|
||||
bool isLEDActive = Ion::LED::getColor() != KDColorBlack;
|
||||
if (checkIfPowerKeyReleased) {
|
||||
/* Wait until power is released to avoid restarting just after suspending */
|
||||
bool isPowerDown = true;
|
||||
@@ -17,28 +18,28 @@ void Ion::Power::suspend(bool checkIfPowerKeyReleased) {
|
||||
isPowerDown = scan.keyDown(Keyboard::Key::B2);
|
||||
}
|
||||
}
|
||||
Device::shutdownPeripherals();
|
||||
Device::shutdownPeripherals(isLEDActive);
|
||||
|
||||
PWR.CR()->setLPDS(true); // Turn the regulator off. Takes longer to wake up.
|
||||
PWR.CR()->setFPDS(true); // Put the flash to sleep. Takes longer to wake up.
|
||||
CM4.SCR()->setSLEEPDEEP(true);
|
||||
CM4.SCR()->setSLEEPDEEP(!isLEDActive);
|
||||
|
||||
WakeUp::Device::onUSBPlugging();
|
||||
#if LED_WHILE_CHARGING
|
||||
WakeUp::Device::onChargingEvent();
|
||||
#endif
|
||||
while (1) {
|
||||
#if LED_WHILE_CHARGING
|
||||
#if EPSILON_LED_WHILE_CHARGING
|
||||
/* Update LEDS
|
||||
* if the standby mode was stopped due to a "stop charging" event, we wait
|
||||
* a while to be sure that the plug state of the USB is up-to-date. */
|
||||
msleep(200);
|
||||
LED::Device::enforceState(Battery::isCharging(), USB::isPlugged(), false);
|
||||
//Ion::LED::setCharging(Ion::USB::isPlugged(), Ion::Battery::isCharging());
|
||||
#endif
|
||||
|
||||
WakeUp::Device::onPowerKeyDown();
|
||||
WakeUp::Device::onUSBPlugging();
|
||||
#if EPSILON_LED_WHILE_CHARGING
|
||||
WakeUp::Device::onChargingEvent();
|
||||
#endif
|
||||
|
||||
Device::shutdownClocks();
|
||||
Device::shutdownClocks(isLEDActive);
|
||||
|
||||
/* To enter sleep, we need to issue a WFE instruction, which waits for the
|
||||
* event flag to be set and then clears it. However, the event flag might
|
||||
@@ -47,7 +48,7 @@ void Ion::Power::suspend(bool checkIfPowerKeyReleased) {
|
||||
* to clear it, and then a second WFE to wait for a _new_ event. */
|
||||
asm("sev");
|
||||
asm("wfe");
|
||||
msleep(1);
|
||||
asm("nop");
|
||||
asm("wfe");
|
||||
|
||||
Device::initClocks();
|
||||
|
||||
@@ -9,7 +9,7 @@ public:
|
||||
public:
|
||||
REGS_BOOL_FIELD(HSION, 0);
|
||||
REGS_BOOL_FIELD(HSEON, 16);
|
||||
REGS_BOOL_FIELD(HSERDY, 17);
|
||||
REGS_BOOL_FIELD_R(HSERDY, 17);
|
||||
REGS_BOOL_FIELD(PLLON, 24);
|
||||
REGS_BOOL_FIELD(PLLRDY, 25);
|
||||
};
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
AHBDividedBy8 = 6,
|
||||
AHBDividedBy16 = 7
|
||||
};
|
||||
void setPPRE1(APBPrescaler p) volatile { setBitRange(12, 10, (uint32_t)p); }
|
||||
void setPPRE1(APBPrescaler r) volatile { setBitRange(12, 10, (uint32_t)r); }
|
||||
};
|
||||
|
||||
class AHB1ENR : public Register32 {
|
||||
@@ -107,6 +107,19 @@ public:
|
||||
REGS_BOOL_FIELD(SYSCFGEN, 14);
|
||||
};
|
||||
|
||||
class AHB1LPENR : public Register32 {
|
||||
public:
|
||||
using Register32::Register32;
|
||||
REGS_BOOL_FIELD(GPIOBLPEN, 1);
|
||||
REGS_BOOL_FIELD(GPIOCLPEN, 2);
|
||||
};
|
||||
|
||||
class APB1LPENR : public Register32 {
|
||||
public:
|
||||
using Register32::Register32;
|
||||
REGS_BOOL_FIELD(TIM3LPEN, 1);
|
||||
};
|
||||
|
||||
class DCKCFGR2 : Register32 {
|
||||
public:
|
||||
REGS_BOOL_FIELD(CK48MSEL, 27);
|
||||
@@ -122,6 +135,8 @@ public:
|
||||
REGS_REGISTER_AT(AHB3ENR, 0x38);
|
||||
REGS_REGISTER_AT(APB1ENR, 0x40);
|
||||
REGS_REGISTER_AT(APB2ENR, 0x44);
|
||||
REGS_REGISTER_AT(AHB1LPENR, 0x50);
|
||||
REGS_REGISTER_AT(APB1LPENR, 0x60);
|
||||
REGS_REGISTER_AT(DCKCFGR2, 0x94);
|
||||
private:
|
||||
constexpr uint32_t Base() const {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "register.h"
|
||||
|
||||
template <typename RegisterWidth>
|
||||
class TIM {
|
||||
public:
|
||||
class CR1 : Register16 {
|
||||
@@ -63,10 +64,10 @@ public:
|
||||
|
||||
class PSC : public Register16 {};
|
||||
class ARR : public Register16 {};
|
||||
class CCR1 : public Register16 {};
|
||||
class CCR2 : public Register16 {};
|
||||
class CCR3 : public Register16 {};
|
||||
class CCR4 : public Register16 {};
|
||||
class CCR1 : public RegisterWidth {};
|
||||
class CCR2 : public RegisterWidth {};
|
||||
class CCR3 : public RegisterWidth {};
|
||||
class CCR4 : public RegisterWidth {};
|
||||
|
||||
constexpr TIM(int i) : m_index(i) {}
|
||||
REGS_REGISTER_AT(CR1, 0x0);
|
||||
@@ -81,12 +82,19 @@ public:
|
||||
REGS_REGISTER_AT(BDTR, 0x44);
|
||||
private:
|
||||
constexpr uint32_t Base() const {
|
||||
return (m_index == 1 ? 0x40010000 : 0x40000000 + 0x400*(m_index-2));
|
||||
};
|
||||
return (m_index == 1 ? 0x40010000 :
|
||||
(m_index <= 7 ? 0x40000000 + 0x400*(m_index-2) :
|
||||
(m_index == 8 ? 0x40010400 :
|
||||
(m_index <= 11 ? 0x40014000 + 0x400*(m_index-9) :
|
||||
0x40001800 + 0x400*(m_index-12)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
int m_index;
|
||||
};
|
||||
|
||||
constexpr TIM TIM1(1);
|
||||
constexpr TIM TIM3(3);
|
||||
constexpr TIM<Register16> TIM3(3);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,7 +31,7 @@ void onUSBPlugging() {
|
||||
SYSCFG.EXTICR3()->setEXTI(USB::Device::VbusPin.pin(), USB::Device::VbusPin.group());
|
||||
|
||||
EXTI.EMR()->set(USB::Device::VbusPin.pin(), true);
|
||||
#if LED_WHILE_CHARGING
|
||||
#if EPSILON_LED_WHILE_CHARGING
|
||||
EXTI.FTSR()->set(USB::Device::VbusPin.pin(), true);
|
||||
#endif
|
||||
EXTI.RTSR()->set(USB::Device::VbusPin.pin(), true);
|
||||
|
||||
@@ -1,4 +1,15 @@
|
||||
#include <ion/led.h>
|
||||
|
||||
void Ion::LED::setColor(KDColor c) {
|
||||
namespace Ion {
|
||||
namespace LED {
|
||||
|
||||
KDColor getColor() {
|
||||
return KDColorBlack;
|
||||
}
|
||||
|
||||
void setColor(KDColor c) {}
|
||||
|
||||
void setBlinking(float period, float dutyCycle) {}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
objs += $(addprefix ion/src/simulator/, \
|
||||
init.o\
|
||||
led.o\
|
||||
)
|
||||
|
||||
objs += $(addprefix ion/src/simulator/boot/, main.o)
|
||||
@@ -17,6 +16,7 @@ objs += $(addprefix ion/src/shared/, \
|
||||
dummy/backlight.o \
|
||||
dummy/battery.o \
|
||||
dummy/fcc_id.o \
|
||||
dummy/led.o \
|
||||
dummy/serial_number.o \
|
||||
dummy/usb.o \
|
||||
)
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#include <ion/led.h>
|
||||
|
||||
void Ion::LED::setColor(KDColor c) {
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user