SAE Teensy ECU
IIT SAE Microcontroller programming
Loading...
Searching...
No Matches
SDBC.h
1#pragma once
2#include <stdint.h>
3
4#include "Canbus.h"
5#include "ECUGlobalConfig.h"
6#include "Log.h"
7
8#include "SDBC_class.hpp"
9#include "SDBC_gen.hpp"
10
11namespace SDBC {
12
13LOG_TAG ID = "SDBC";
14
15namespace Pins { // TODO: replace Pin lib API w/ this
16
17const gpio_val_t gpio_values[ACTIVE_NODE::gpioMax];
18const virt_val_t virt_values[ACTIVE_NODE::virtCount];
19
20template <typename T>
21void __set(const GPIO &pin, T value) {
22 if (pin.pin >= VIRT_ID_OFFSET) { // NOTE: setting input virt allowed
23 virt_values[pin.pin - VIRT_ID_OFFSET] = value;
24 } else if (pin.outOrIn) {
25 if (pin.pin < ACTIVE_NODE::gpioMax)
26 gpio_values[pin.pin] = value;
27 if (pin.digOrAnl)
28 digitalWriteFast(pin.pin, value);
29 else
30 analogWrite(pin.pin, value);
31 }
32}
33template <typename T>
34inline void checkSettee(const SDBC::SIG *settee, T value) {
35 if (settee != nullptr) { // has a value setter
36 settee->msg->setSig(settee, value));
37 // TODO: trigger CAN message to be sent
38 }
39}
40template <typename T = gpio_val_t>
41void set(const GPIO &pin, T value) {
42 // FIXME: check if value is out of range than capable analog resolution? clamp to min max?
43 checkSettee<T>(pin.settee, value);
44 __set<T>(pin, value);
45}
46template <typename T = virt_val_t>
47void set(const VIRT &pin, T value) {
48 checkSettee<T>(pin.settee, value);
49 __set<T>(pin, value);
50}
51template <typename T = gpio_val_t>
52void set(const int pin, T value) { // Discourage direct pin access
53 auto iter = ACTIVE_NODE.__pinMap.find(pin);
54 if (iter != ACTIVE_NODE.__pinMap.end()) { // Check if pin is mapped
55 SDBC::GPIO *gpio = iter->second;
56 if (gpio->isVirt)
57 return set(*(VIRT *)gpio, value);
58 return set<T>(*gpio, value);
59 }
60 if (pin < VIRT_ID_OFFSET) { // VIRTs can only be set by reference, not indirectly
61 if (pin < ACTIVE_NODE::gpioMax)
62 gpio_values[pin.pin] = value;
63 }
64}
65
66template <typename T = int>
67T __get(const GPIO &pin) { // NOTE: get allowed regardless of input or output
68
69 if (pin.pin >= VIRT_ID_OFFSET) {
70 return virt_values[pin.pin - VIRT_ID_OFFSET];
71 }
72
73 if (pin.pin >= ACTIVE_NODE::gpioMax) {
74 Log.e(ID, "Attempting to read a pin that is out of range", pin.pin);
75 return 0;
76 }
77
78 if (pin.outOrIn) { // TODO: print verbose when "reading" output value
79 return gpio_values[pin.pin];
80 }
81
82 if (pin.digOrAnl) {
83 return (gpio_values[pin.pin] = digitalReadFast(pin.pin, value));
84 }
85
86 return (gpio_values[pin.pin] = analogRead(pin.pin, value));
87}
88template <typename T = gpio_val_t>
89inline T get(const GPIO &pin) {
90 return __get<T>(pin);
91}
92template <typename T = virt_val_t>
93inline T get(const VIRT &pin) {
94 return __get<T>(pin);
95}
96} // namespace Pins
97
98// TODO: call upon receiving CAN message, will replace current callback
99void incoming(const uint32_t addr, volatile uint8_t *buf) { // NOTE: currently assuming all 8 bytes are sent
100 auto iter = MessageMap.find(addr);
101 if (iter == MessageMap.end()) // Check if address is relevant
102 return;
103
104 auto msg = iter->second;
105 if (msg->outgoing) // Check if message is actually incoming
106 return;
107
108 msg->value.raw = *(volatile uint64_t *)buf; // Update buffer
109
110 if (!msg->hasValueSetter)
111 return;
112
113 for (size_t i = 0; i < msg->signalCount; i++) {
114 auto sig = msg->SIGNALS[i];
115 if (sig->setter == nullptr)
116 continue;
117 switch (sig->dataType) {
118#define X(dt_id, typ) \
119 case dt::dt_id: \
120 Pins::__set<typ>(*sig->setter, msg->getSig<typ>(sig)); \
121 break;
122 SDBC_TYPE_DEFINITIONS
123#undef X
124 default:
125 break;
126 }
127 }
128}
129
130// TODO: add option to have messages with value setters to be polled instead, not event driven like with Pins set. Sig will have setter defined versus settee defined in GPIO itself
131void update() {
132}
133
134/* OLD */
135
136// template <typename T>
137// void post(const SIG signal, T data) {
138// if (ACTIVE_NODE.nodeID == signal.nodeID) { // Signal is sent by this node
139// signal.msg->setSig(signal, *((uint64_t *)&data));
140// } else if (!signal.msg->outgoing) { // Signal is received by a node
141// signal.msg->setSig(signal, *((uint64_t *)&data));
142// // TODO: immediately send entire message here on CAN line or setup to be sent
143// } else {
144// Log.w(ID, "Posting signal not relevant to node", signal.nodeID);
145// }
146// }
147
148// template <typename T>
149// constexpr T get(const SIG signal) {
150// uint64_t data = signal.msg->value.raw;
151// data &= signal.bitMask;
152// data >>= signal.bitPos;
153// return *(T *)&data;
154// }
155
156// // TODO: call upon pin update, check if it matches a value setter
157
158// // TODO: call upon setting a pin value (GPIO/VIRT)
159// void updatePin(const uint32_t pin) {
160// auto iter = ACTIVE_NODE.ValueSetMap.find(pin);
161// if (iter != ACTIVE_NODE.ValueSetMap.end()) { // Check if pin is a value setter
162// auto signal = iter->second;
163
164// Pins::set(ACTIVE_NODE.PIN.ANALOG_TEST, 45);
165// Pins::set(ACTIVE_NODE.PIN.START_LED, 45);
166// }
167// }
168
169// // TODO: call upon relevant message update from CAN line
170// void update(const SIG signal) {
171// if (signal.setter != nullptr)
172// if (signal.msg->outgoing) {
173// switch (signal.dataType) {
174// // TODO: ensure setPin can set VIRT pins to any value type, not just integers
175// // FIXME: use template to set/get pin values to include VIRTs? integer by default
176// #define X(dt_id, typ) \
177// case dt::dt_id: \
178// Pins::setPinValue(signal.setter->pin, get<typ>(signal)); \
179// break;
180// SDBC_TYPE_DEFINITIONS
181// #undef X
182// default:
183// break;
184// }
185// } else {
186// post(signal, Pins::getPinValue(signal.setter->pin));
187// }
188// }
189
190} // namespace SDBC
FlexCAN_T4 wrapper.
Configure global build properties.
Special logging functionality.
const char * LOG_TAG
Type definition of logging tags This typedef is necessary to allow for easier manipulation of code by...
Definition Log.h:48
Logging::Log_t Log
The global logging object.
Get and set values to predefined pins.
Definition Pins.h:85
Definition SDBC.h:11
void e(LOG_TAG TAG, LOG_MSG message)
Log a string using an error tag.