diff --git a/ion/src/device/battery.cpp b/ion/src/device/battery.cpp index 00ee29270..60df14463 100644 --- a/ion/src/device/battery.cpp +++ b/ion/src/device/battery.cpp @@ -48,13 +48,7 @@ namespace Battery { namespace Device { void init() { - /* Step 1 - Configure the GPIOs - * The BAT_CHRG pin is connected to the Li-Po charging IC. That pin uses an - * open-drain output. Open-drain output are either connected to ground or left - * floating. To interact with such an output, our input must therefore be - * pulled up. */ - ChargingGPIO.MODER()->setMode(ChargingPin, GPIO::MODER::Mode::Input); - ChargingGPIO.PUPDR()->setPull(ChargingPin, GPIO::PUPDR::Pull::Up); + initGPIO(); /* The BAT_SNS pin is connected to Vbat through a divider bridge. It therefore * has a voltage of Vbat/2. We'll measure this using ADC channel 0. */ @@ -70,12 +64,39 @@ void init() { ADC.SMPR()->setSamplingTime(ADCChannel, ADC::SMPR::SamplingTime::Cycles480); // Use the max sampling time } +void initGPIO() { + /* Step 1 - Configure the GPIOs + * The BAT_CHRG pin is connected to the Li-Po charging IC. That pin uses an + * open-drain output. Open-drain output are either connected to ground or left + * floating. To interact with such an output, our input must therefore be + * pulled up. */ + ChargingGPIO.MODER()->setMode(ChargingPin, GPIO::MODER::Mode::Input); + ChargingGPIO.PUPDR()->setPull(ChargingPin, GPIO::PUPDR::Pull::Up); +} + void shutdown() { // Disable the ADC ADC.CR2()->setADON(false); RCC.APB2ENR()->setADC1EN(false); } +void generateWakeUpEventForChargingState() { + initGPIO(); + + /* Warning: pins with the same number in different groups cannot be set as + * source input for EXTI at the same time. Here, EXTICR1 register is filled + * between position 0-3 (charging pin = 0) with + * 0000 (ChargingGPIO = group A). */ + SYSCFG.EXTICR1()->setEXTI(ChargingPin, ChargingGPIO); + + EXTI.EMR()->set(ChargingPin, true); + + /* We need to detect when the battery starts and stops charging. We set the + * wake up event on the falling and rising edge. */ + EXTI.FTSR()->set(ChargingPin, true); + EXTI.RTSR()->set(ChargingPin, true); +} + } } } diff --git a/ion/src/device/battery.h b/ion/src/device/battery.h index ef558dc86..1829b0ad1 100644 --- a/ion/src/device/battery.h +++ b/ion/src/device/battery.h @@ -17,6 +17,7 @@ void init(); void shutdown(); void initGPIO(); void initADC(); +void generateWakeUpEventForChargingState(); constexpr GPIO ChargingGPIO = GPIOA; constexpr uint8_t ChargingPin = 0; diff --git a/ion/src/device/keyboard.cpp b/ion/src/device/keyboard.cpp index b0b962cfa..5969ea399 100644 --- a/ion/src/device/keyboard.cpp +++ b/ion/src/device/keyboard.cpp @@ -117,18 +117,23 @@ void shutdown() { } } -void generateWakeUpEventForKey(Key k) { - uint8_t rowPin = RowPins[rowForKey(k)]; +void generateWakeUpEventForPowerKey() { + Key key = Key::B2; + uint8_t rowPin = RowPins[rowForKey(key)]; RowGPIO.MODER()->setMode(rowPin, GPIO::MODER::Mode::Output); RowGPIO.OTYPER()->setType(rowPin, GPIO::OTYPER::Type::OpenDrain); RowGPIO.ODR()->set(rowPin, 0); - uint8_t column = columnForKey(k); + uint8_t column = columnForKey(key); uint8_t columnPin = ColumnPins[column]; ColumnGPIO.MODER()->setMode(columnPin, GPIO::MODER::Mode::Input); ColumnGPIO.PUPDR()->setPull(columnPin, GPIO::PUPDR::Pull::Up); + /* Warning: pins with the same number in different groups cannot be set as + * source input for EXTI at the same time. Here, EXTICR1 register is filled + * between position 4-7 (column pin = 1) with 0010 (ColumnGPIO = group C). */ + SYSCFG.EXTICR1()->setEXTI(columnPin, ColumnGPIO); EXTI.EMR()->set(columnPin, true); diff --git a/ion/src/device/keyboard.h b/ion/src/device/keyboard.h index d9ed2e18d..3d8d59d65 100644 --- a/ion/src/device/keyboard.h +++ b/ion/src/device/keyboard.h @@ -45,7 +45,7 @@ inline uint8_t columnForKey(Key key) { return (int)key%numberOfColumns; } -void generateWakeUpEventForKey(Key k); +void generateWakeUpEventForPowerKey(); } } diff --git a/ion/src/device/power.cpp b/ion/src/device/power.cpp index 966cc2add..e3249e69a 100644 --- a/ion/src/device/power.cpp +++ b/ion/src/device/power.cpp @@ -12,7 +12,7 @@ void Ion::Power::suspend() { PWR.CR()->setFPDS(true); // Put the flash to sleep. Takes longer to wake up. CM4.SCR()->setSLEEPDEEP(true); - Keyboard::Device::generateWakeUpEventForKey(Ion::Keyboard::Key::B2); + Keyboard::Device::generateWakeUpEventForPowerKey(); Device::shutdownClocks(); diff --git a/ion/src/device/usb.cpp b/ion/src/device/usb.cpp index f525079df..0ea0786e6 100644 --- a/ion/src/device/usb.cpp +++ b/ion/src/device/usb.cpp @@ -17,6 +17,10 @@ namespace USB { namespace Device { void init() { + initGPIO(); +} + +void initGPIO() { /* Configure the GPIO * The VBUS pin is connected to the USB VBUS port. To read if the USB is * plugged, the pin must be pulled down. */ @@ -29,6 +33,17 @@ void shutdown() { VbusPin.group().PUPDR()->setPull(VbusPin.pin(), GPIO::PUPDR::Pull::None); } +void generateWakeUpEventForUSBPlug() { + initGPIO(); + /* Warning: pins with the same number in different groups cannot be set as + * source input for EXTI at the same time. Here, EXTICR3 register is + * filled between position 4-7 (Vbus pin = 9) with 0000 (Vbus GPIO = group A). */ + SYSCFG.EXTICR3()->setEXTI(VbusPin.pin(), VbusPin.group()); + + EXTI.EMR()->set(VbusPin.pin(), true); + EXTI.FTSR()->set(VbusPin.pin(), true); + EXTI.RTSR()->set(VbusPin.pin(), true); +} } } } diff --git a/ion/src/device/usb.h b/ion/src/device/usb.h index 4c1a03227..8d92d4fa2 100644 --- a/ion/src/device/usb.h +++ b/ion/src/device/usb.h @@ -13,7 +13,9 @@ namespace Device { */ void init(); +void initGPIO(); void shutdown(); +void generateWakeUpEventForUSBPlug(); constexpr static GPIOPin VbusPin = GPIOPin(GPIOA, 9);