mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-19 05:40:38 +01:00
[ion] Enable suspend/resume
Change-Id: I1fe580de7f98b95c768416ca889a7d74dad851ca
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include <ion/events.h>
|
||||
#include <ion/keyboard.h>
|
||||
#include <ion/led.h>
|
||||
#include <ion/power.h>
|
||||
|
||||
|
||||
/* ION is not your regular library. It is a library you link against, but it
|
||||
|
||||
12
ion/include/ion/power.h
Normal file
12
ion/include/ion/power.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef ION_POWER_H
|
||||
#define ION_POWER_H
|
||||
|
||||
namespace Ion {
|
||||
namespace Power {
|
||||
|
||||
void suspend();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -6,6 +6,7 @@ objs += $(addprefix ion/src/device/, \
|
||||
heap.o\
|
||||
keyboard.o\
|
||||
led.o\
|
||||
power.o\
|
||||
)
|
||||
|
||||
# When using the register.h C++ file in production mode, we expect the compiler
|
||||
|
||||
@@ -53,6 +53,7 @@ void Ion::Device::initClocks() {
|
||||
RCC.APB1ENR()->setTIM3EN(true);
|
||||
|
||||
RCC.APB2ENR()->setADC1EN(true);
|
||||
RCC.APB2ENR()->setSYSCFGEN(true);
|
||||
}
|
||||
|
||||
void Ion::Device::initFPU() {
|
||||
|
||||
@@ -79,7 +79,11 @@ bool keyDown(Key k) {
|
||||
|
||||
// Private Ion::Keyboard::Device methods
|
||||
|
||||
void Ion::Keyboard::Device::init() {
|
||||
namespace Ion {
|
||||
namespace Keyboard {
|
||||
namespace Device {
|
||||
|
||||
void init() {
|
||||
for (uint8_t i=0; i<numberOfRows; i++) {
|
||||
uint8_t pin = RowPins[i];
|
||||
RowGPIO.MODER()->setMode(pin, GPIO::MODER::Mode::Output);
|
||||
@@ -92,3 +96,32 @@ void Ion::Keyboard::Device::init() {
|
||||
ColumnGPIO.PUPDR()->setPull(pin, GPIO::PUPDR::Pull::Up);
|
||||
}
|
||||
}
|
||||
|
||||
void generateWakeUpEventForKey(Ion::Keyboard::Key k) {
|
||||
// We're driving the rows and reading the columns.
|
||||
int row = rowForKey(k);
|
||||
for (uint8_t i=0; i<numberOfRows; i++) {
|
||||
/* In open-drain mode, a 0 in the register drives the pin low, and a 1 lets
|
||||
* the pin floating (Hi-Z). So we want to set the current row to zero and
|
||||
* all the others to 1. */
|
||||
bool state = (i == row ? 0 : 1);
|
||||
uint8_t pin = RowPins[i];
|
||||
RowGPIO.ODR()->set(pin, state);
|
||||
}
|
||||
|
||||
uint8_t column = columnForKey(k);
|
||||
uint8_t columnPin = ColumnPins[column];
|
||||
|
||||
SYSCFG.EXTICR1()->setEXTI(columnPin, ColumnGPIO);
|
||||
|
||||
EXTI.EMR()->set(columnPin, true);
|
||||
|
||||
/* When the key is pressed, it will go from 1 (because it's pulled up) to
|
||||
* zero (because it's connected to the open-drain output. In other words,
|
||||
* we're waiting for a falling edge. */
|
||||
EXTI.FTSR()->set(columnPin, true);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef ION_DEVICE_KEYBOARD_H
|
||||
#define ION_DEVICE_KEYBOARD_H
|
||||
|
||||
#include <ion/keyboard.h>
|
||||
#include "regs/regs.h"
|
||||
|
||||
namespace Ion {
|
||||
@@ -43,6 +44,8 @@ inline uint8_t columnForKey(Ion::Keyboard::Key key) {
|
||||
return (int)key%numberOfColumns;
|
||||
}
|
||||
|
||||
void generateWakeUpEventForKey(Ion::Keyboard::Key k);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
10
ion/src/device/power.cpp
Normal file
10
ion/src/device/power.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#include <ion/power.h>
|
||||
#include <ion/display.h>
|
||||
#include "keyboard.h"
|
||||
|
||||
void Ion::Power::suspend() {
|
||||
Display::setBacklightIntensity(0);
|
||||
Keyboard::Device::generateWakeUpEventForKey(Ion::Keyboard::Key::J1);
|
||||
asm("wfe");
|
||||
Display::setBacklightIntensity(0xFF);
|
||||
}
|
||||
30
ion/src/device/regs/exti.h
Normal file
30
ion/src/device/regs/exti.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef REGS_EXTI_H
|
||||
#define REGS_EXTI_H
|
||||
|
||||
#include "register.h"
|
||||
|
||||
class EXTI {
|
||||
public:
|
||||
class MaskRegister : Register32 {
|
||||
public:
|
||||
bool get(int index) { return (bool)getBitRange(index, index); }
|
||||
void set(int index, bool state) volatile { setBitRange(index, index, state); }
|
||||
};
|
||||
|
||||
//class IMR : public MaskRegister { };
|
||||
class EMR : public MaskRegister { };
|
||||
class FTSR : public MaskRegister { };
|
||||
|
||||
constexpr EXTI() {};
|
||||
//REGS_REGISTER_AT(IMR, 0x00);
|
||||
REGS_REGISTER_AT(EMR, 0x04);
|
||||
REGS_REGISTER_AT(FTSR, 0x0C);
|
||||
private:
|
||||
constexpr uint32_t Base() const {
|
||||
return 0x40013C00;
|
||||
}
|
||||
};
|
||||
|
||||
constexpr EXTI EXTI;
|
||||
|
||||
#endif
|
||||
@@ -69,6 +69,7 @@ public:
|
||||
};
|
||||
|
||||
constexpr GPIO(int i) : m_index(i) {}
|
||||
operator int() const { return m_index; }
|
||||
REGS_REGISTER_AT(MODER, 0x00);
|
||||
REGS_REGISTER_AT(OTYPER, 0x04);
|
||||
REGS_REGISTER_AT(PUPDR, 0x0C);
|
||||
|
||||
@@ -36,6 +36,7 @@ public:
|
||||
public:
|
||||
REGS_BOOL_FIELD(TIM1EN, 0);
|
||||
REGS_BOOL_FIELD(ADC1EN, 8);
|
||||
REGS_BOOL_FIELD(SYSCFGEN, 14);
|
||||
};
|
||||
|
||||
constexpr RCC() {};
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
#define REGS_REGS_H
|
||||
|
||||
#include "adc.h"
|
||||
#include "exti.h"
|
||||
#include "cm4.h"
|
||||
#include "fsmc.h"
|
||||
#include "rcc.h"
|
||||
#include "gpio.h"
|
||||
#include "syscfg.h"
|
||||
#include "tim.h"
|
||||
|
||||
#endif
|
||||
|
||||
25
ion/src/device/regs/syscfg.h
Normal file
25
ion/src/device/regs/syscfg.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef REGS_SYSCFG_H
|
||||
#define REGS_SYSCFG_H
|
||||
|
||||
#include "register.h"
|
||||
|
||||
#include "gpio.h"
|
||||
|
||||
class SYSCFG {
|
||||
public:
|
||||
class EXTICR1 : Register32 {
|
||||
public:
|
||||
void setEXTI(int index, GPIO gpio) volatile { setBitRange(4*index+3, 4*index, (uint32_t)gpio); }
|
||||
};
|
||||
|
||||
constexpr SYSCFG() {};
|
||||
REGS_REGISTER_AT(EXTICR1, 0x08);
|
||||
private:
|
||||
constexpr uint32_t Base() const {
|
||||
return 0x40013800;
|
||||
}
|
||||
};
|
||||
|
||||
constexpr SYSCFG SYSCFG;
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user