This repository has been archived by the owner on Dec 2, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
DigInChSubsys.cpp
127 lines (102 loc) · 3.26 KB
/
DigInChSubsys.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Copyright (c) 2018 Formula Slug. All Rights Reserved.
#include "DigInChSubsys.h"
#include "Event.h"
#include "ch.hpp"
#include "hal.h"
#include "mcuconfFs.h"
DigInChSubsys::DigInChSubsys(EventQueue& eq) : m_eventQueue(eq) {}
/**
* TODO: Implement sampling frequency input per-pin
*/
bool DigInChSubsys::addPin(DigitalInput pin) {
// fail if pin already added
if (registered(pin)) return false;
// stop the subsystem to synchronize configuration with sampling
// thread (run function)
stop();
// set the pin mode
palSetPadMode(getPort(pin), getPinNum(pin), PAL_MODE_INPUT_PULLUP);
// add the pin internally
m_pins[static_cast<uint32_t>(pin)] = true;
// init current state
m_pinStates[static_cast<uint32_t>(pin)] = getState(pin);
m_numPins++;
// start the subsystem again with new configuration
start();
// return success
return true;
}
void DigInChSubsys::runThread() {
while (true) {
if (m_subsysActive) {
std::vector<Event> events;
for (uint32_t i = 0; i < m_numPins; i++) {
// check for transition in pin state
bool currentState = getState(static_cast<DigitalInput>(i));
// if pin changed states
if (currentState != getSavedState(static_cast<DigitalInput>(i))) {
// save change
m_pinStates[i] = currentState;
// queue event
events.push_back(Event(Event::Type::kDigInTransition,
static_cast<DigitalInput>(i), currentState));
}
}
// post events if present
if (events.size() > 0) {
m_eventQueue.push(events);
}
}
// sleep to yield processing until next sample of channels
chThdSleepMilliseconds(m_sampleClkMs);
}
}
bool DigInChSubsys::removePin(DigitalInput pin) {
// return failure if pin wasn't added
if (!registered(pin)) return false;
// stop the interface momentarily
stop();
// remove the pin internally
m_pins[static_cast<uint32_t>(pin)] = false;
m_numPins--;
// start the subsystem with the new configuration (if at least
// one pin is still registered)
if (m_numPins > 0) start();
// return success
return false;
}
/**
* @note Public interface only permits access to subsystem's
* internally saved pin state, rather than pin value, in order
* to ensure consistent in user's implementation
*/
bool DigInChSubsys::getSavedState(DigitalInput p) {
return m_pinStates[static_cast<uint32_t>(p)];
}
// TODO: implement full subsystem, then implement pin adding
void DigInChSubsys::start() { m_subsysActive = true; }
/**
* @note Subsystem should be stopped before any configurations are
* changed. Otherwise, partial configuration will temporarily
* corrupt conversion events send to the user's event queue
*/
void DigInChSubsys::stop() {
// TODO: tear down the subystem
m_subsysActive = false;
}
bool DigInChSubsys::registered(DigitalInput p) {
if (m_pins[static_cast<uint32_t>(p)]) {
return true;
} else {
return false;
}
}
uint32_t DigInChSubsys::getPinNum(DigitalInput p) {
return kPinMap[static_cast<uint32_t>(p)];
}
stm32_gpio_t* DigInChSubsys::getPort(DigitalInput p) {
return kPortMap[static_cast<uint32_t>(p)];
}
bool DigInChSubsys::getState(DigitalInput p) {
return palReadPad(getPort(p), getPinNum(p)) != 0;
}