Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 753c5facb0 | |||
| 350405ac45 | |||
| 839ebf5078 | |||
| 58b2f941db | |||
| aa026e877b | |||
| 752c837195 | |||
| c928aa18a1 | |||
| 7fcd1668db | |||
| b5006d7b6e | |||
| 6e2ccc8b15 |
@@ -1,3 +1,6 @@
|
||||
sunnypilot Version 2026.002.000 (2026-xx-xx)
|
||||
========================
|
||||
|
||||
sunnypilot Version 2026.001.000 (2026-05-06)
|
||||
========================
|
||||
* What's Changed (sunnypilot/sunnypilot)
|
||||
|
||||
+133
-165
@@ -24173,17 +24173,17 @@ const ::capnp::_::RawSchema s_fc010c40147563b0 = {
|
||||
2, 8, i_fc010c40147563b0, nullptr, nullptr, { &s_fc010c40147563b0, nullptr, nullptr, 0, 0, nullptr }, false
|
||||
};
|
||||
#endif // !CAPNP_LITE
|
||||
static const ::capnp::_::AlignedData<173> b_c9f73bb1cdf28a6a = {
|
||||
static const ::capnp::_::AlignedData<221> b_c9f73bb1cdf28a6a = {
|
||||
{ 0, 0, 0, 0, 5, 0, 6, 0,
|
||||
106, 138, 242, 205, 177, 59, 247, 201,
|
||||
24, 0, 0, 0, 1, 0, 5, 0,
|
||||
24, 0, 0, 0, 1, 0, 4, 0,
|
||||
176, 99, 117, 20, 64, 12, 1, 252,
|
||||
6, 0, 7, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
21, 0, 0, 0, 26, 1, 0, 0,
|
||||
37, 0, 0, 0, 7, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
33, 0, 0, 0, 255, 1, 0, 0,
|
||||
33, 0, 0, 0, 167, 2, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
108, 111, 103, 46, 99, 97, 112, 110,
|
||||
@@ -24192,70 +24192,91 @@ static const ::capnp::_::AlignedData<173> b_c9f73bb1cdf28a6a = {
|
||||
68, 114, 105, 118, 101, 114, 68, 97,
|
||||
116, 97, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 1, 0, 1, 0,
|
||||
36, 0, 0, 0, 3, 0, 4, 0,
|
||||
48, 0, 0, 0, 3, 0, 4, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 1, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
237, 0, 0, 0, 130, 0, 0, 0,
|
||||
65, 1, 0, 0, 130, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
236, 0, 0, 0, 3, 0, 1, 0,
|
||||
8, 1, 0, 0, 2, 0, 1, 0,
|
||||
64, 1, 0, 0, 3, 0, 1, 0,
|
||||
92, 1, 0, 0, 2, 0, 1, 0,
|
||||
1, 0, 0, 0, 1, 0, 0, 0,
|
||||
0, 0, 1, 0, 1, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
5, 1, 0, 0, 154, 0, 0, 0,
|
||||
89, 1, 0, 0, 154, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
8, 1, 0, 0, 3, 0, 1, 0,
|
||||
36, 1, 0, 0, 2, 0, 1, 0,
|
||||
92, 1, 0, 0, 3, 0, 1, 0,
|
||||
120, 1, 0, 0, 2, 0, 1, 0,
|
||||
2, 0, 0, 0, 2, 0, 0, 0,
|
||||
0, 0, 1, 0, 2, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
33, 1, 0, 0, 106, 0, 0, 0,
|
||||
117, 1, 0, 0, 106, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
32, 1, 0, 0, 3, 0, 1, 0,
|
||||
60, 1, 0, 0, 2, 0, 1, 0,
|
||||
116, 1, 0, 0, 3, 0, 1, 0,
|
||||
144, 1, 0, 0, 2, 0, 1, 0,
|
||||
3, 0, 0, 0, 3, 0, 0, 0,
|
||||
0, 0, 1, 0, 3, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
57, 1, 0, 0, 130, 0, 0, 0,
|
||||
141, 1, 0, 0, 130, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
56, 1, 0, 0, 3, 0, 1, 0,
|
||||
84, 1, 0, 0, 2, 0, 1, 0,
|
||||
140, 1, 0, 0, 3, 0, 1, 0,
|
||||
168, 1, 0, 0, 2, 0, 1, 0,
|
||||
4, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 1, 0, 4, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
81, 1, 0, 0, 74, 0, 0, 0,
|
||||
165, 1, 0, 0, 74, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
80, 1, 0, 0, 3, 0, 1, 0,
|
||||
92, 1, 0, 0, 2, 0, 1, 0,
|
||||
8, 0, 0, 0, 0, 0, 0, 0,
|
||||
164, 1, 0, 0, 3, 0, 1, 0,
|
||||
176, 1, 0, 0, 2, 0, 1, 0,
|
||||
5, 0, 0, 0, 1, 0, 0, 0,
|
||||
0, 0, 1, 0, 5, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
173, 1, 0, 0, 98, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
172, 1, 0, 0, 3, 0, 1, 0,
|
||||
184, 1, 0, 0, 2, 0, 1, 0,
|
||||
6, 0, 0, 0, 2, 0, 0, 0,
|
||||
0, 0, 1, 0, 6, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
181, 1, 0, 0, 106, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
180, 1, 0, 0, 3, 0, 1, 0,
|
||||
192, 1, 0, 0, 2, 0, 1, 0,
|
||||
7, 0, 0, 0, 3, 0, 0, 0,
|
||||
0, 0, 1, 0, 7, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
189, 1, 0, 0, 114, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
188, 1, 0, 0, 3, 0, 1, 0,
|
||||
200, 1, 0, 0, 2, 0, 1, 0,
|
||||
8, 0, 0, 0, 4, 0, 0, 0,
|
||||
0, 0, 1, 0, 8, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
197, 1, 0, 0, 122, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
196, 1, 0, 0, 3, 0, 1, 0,
|
||||
208, 1, 0, 0, 2, 0, 1, 0,
|
||||
9, 0, 0, 0, 5, 0, 0, 0,
|
||||
0, 0, 1, 0, 9, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
205, 1, 0, 0, 122, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
204, 1, 0, 0, 3, 0, 1, 0,
|
||||
216, 1, 0, 0, 2, 0, 1, 0,
|
||||
11, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 0, 0, 0, 0,
|
||||
6, 86, 193, 227, 157, 60, 112, 217,
|
||||
89, 1, 0, 0, 90, 0, 0, 0,
|
||||
233, 90, 130, 19, 150, 159, 147, 218,
|
||||
213, 1, 0, 0, 90, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
7, 0, 0, 0, 7, 0, 0, 0,
|
||||
10, 0, 0, 0, 7, 0, 0, 0,
|
||||
0, 0, 1, 0, 13, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
69, 1, 0, 0, 82, 0, 0, 0,
|
||||
193, 1, 0, 0, 82, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
68, 1, 0, 0, 3, 0, 1, 0,
|
||||
80, 1, 0, 0, 2, 0, 1, 0,
|
||||
5, 0, 0, 0, 8, 0, 0, 0,
|
||||
0, 0, 1, 0, 14, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
77, 1, 0, 0, 130, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
76, 1, 0, 0, 3, 0, 1, 0,
|
||||
88, 1, 0, 0, 2, 0, 1, 0,
|
||||
6, 0, 0, 0, 9, 0, 0, 0,
|
||||
0, 0, 1, 0, 15, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
85, 1, 0, 0, 122, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
84, 1, 0, 0, 3, 0, 1, 0,
|
||||
96, 1, 0, 0, 2, 0, 1, 0,
|
||||
192, 1, 0, 0, 3, 0, 1, 0,
|
||||
204, 1, 0, 0, 2, 0, 1, 0,
|
||||
102, 97, 99, 101, 79, 114, 105, 101,
|
||||
110, 116, 97, 116, 105, 111, 110, 0,
|
||||
14, 0, 0, 0, 0, 0, 0, 0,
|
||||
@@ -24318,124 +24339,6 @@ static const ::capnp::_::AlignedData<173> b_c9f73bb1cdf28a6a = {
|
||||
10, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
100, 101, 112, 114, 101, 99, 97, 116,
|
||||
101, 100, 0, 0, 0, 0, 0, 0,
|
||||
112, 104, 111, 110, 101, 80, 114, 111,
|
||||
98, 0, 0, 0, 0, 0, 0, 0,
|
||||
10, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
10, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
101, 121, 101, 115, 86, 105, 115, 105,
|
||||
98, 108, 101, 80, 114, 111, 98, 0,
|
||||
10, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
10, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
101, 121, 101, 115, 67, 108, 111, 115,
|
||||
101, 100, 80, 114, 111, 98, 0, 0,
|
||||
10, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
10, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, }
|
||||
};
|
||||
::capnp::word const* const bp_c9f73bb1cdf28a6a = b_c9f73bb1cdf28a6a.words;
|
||||
#if !CAPNP_LITE
|
||||
static const ::capnp::_::RawSchema* const d_c9f73bb1cdf28a6a[] = {
|
||||
&s_d9703c9de3c15606,
|
||||
};
|
||||
static const uint16_t m_c9f73bb1cdf28a6a[] = {5, 8, 7, 0, 1, 2, 3, 4, 6};
|
||||
static const uint16_t i_c9f73bb1cdf28a6a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
|
||||
const ::capnp::_::RawSchema s_c9f73bb1cdf28a6a = {
|
||||
0xc9f73bb1cdf28a6a, b_c9f73bb1cdf28a6a.words, 173, d_c9f73bb1cdf28a6a, m_c9f73bb1cdf28a6a,
|
||||
1, 9, i_c9f73bb1cdf28a6a, nullptr, nullptr, { &s_c9f73bb1cdf28a6a, nullptr, nullptr, 0, 0, nullptr }, false
|
||||
};
|
||||
#endif // !CAPNP_LITE
|
||||
static const ::capnp::_::AlignedData<155> b_d9703c9de3c15606 = {
|
||||
{ 0, 0, 0, 0, 5, 0, 6, 0,
|
||||
6, 86, 193, 227, 157, 60, 112, 217,
|
||||
35, 0, 0, 0, 1, 0, 5, 0,
|
||||
106, 138, 242, 205, 177, 59, 247, 201,
|
||||
6, 0, 7, 0, 1, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
21, 0, 0, 0, 114, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
33, 0, 0, 0, 199, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
108, 111, 103, 46, 99, 97, 112, 110,
|
||||
112, 58, 68, 114, 105, 118, 101, 114,
|
||||
83, 116, 97, 116, 101, 86, 50, 46,
|
||||
68, 114, 105, 118, 101, 114, 68, 97,
|
||||
116, 97, 46, 100, 101, 112, 114, 101,
|
||||
99, 97, 116, 101, 100, 0, 0, 0,
|
||||
32, 0, 0, 0, 3, 0, 4, 0,
|
||||
0, 0, 0, 0, 1, 0, 0, 0,
|
||||
0, 0, 1, 0, 5, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
209, 0, 0, 0, 98, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
208, 0, 0, 0, 3, 0, 1, 0,
|
||||
220, 0, 0, 0, 2, 0, 1, 0,
|
||||
1, 0, 0, 0, 2, 0, 0, 0,
|
||||
0, 0, 1, 0, 6, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
217, 0, 0, 0, 106, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
216, 0, 0, 0, 3, 0, 1, 0,
|
||||
228, 0, 0, 0, 2, 0, 1, 0,
|
||||
2, 0, 0, 0, 3, 0, 0, 0,
|
||||
0, 0, 1, 0, 7, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
225, 0, 0, 0, 114, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
224, 0, 0, 0, 3, 0, 1, 0,
|
||||
236, 0, 0, 0, 2, 0, 1, 0,
|
||||
3, 0, 0, 0, 4, 0, 0, 0,
|
||||
0, 0, 1, 0, 8, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
233, 0, 0, 0, 122, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
232, 0, 0, 0, 3, 0, 1, 0,
|
||||
244, 0, 0, 0, 2, 0, 1, 0,
|
||||
4, 0, 0, 0, 5, 0, 0, 0,
|
||||
0, 0, 1, 0, 9, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
241, 0, 0, 0, 122, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
240, 0, 0, 0, 3, 0, 1, 0,
|
||||
252, 0, 0, 0, 2, 0, 1, 0,
|
||||
6, 0, 0, 0, 6, 0, 0, 0,
|
||||
0, 0, 1, 0, 10, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
249, 0, 0, 0, 106, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
248, 0, 0, 0, 3, 0, 1, 0,
|
||||
4, 1, 0, 0, 2, 0, 1, 0,
|
||||
7, 0, 0, 0, 4, 0, 0, 0,
|
||||
0, 0, 1, 0, 11, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 1, 0, 0, 82, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 3, 0, 1, 0,
|
||||
28, 1, 0, 0, 2, 0, 1, 0,
|
||||
5, 0, 0, 0, 5, 0, 0, 0,
|
||||
0, 0, 1, 0, 12, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
25, 1, 0, 0, 106, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
24, 1, 0, 0, 3, 0, 1, 0,
|
||||
52, 1, 0, 0, 2, 0, 1, 0,
|
||||
108, 101, 102, 116, 69, 121, 101, 80,
|
||||
114, 111, 98, 0, 0, 0, 0, 0,
|
||||
10, 0, 0, 0, 0, 0, 0, 0,
|
||||
@@ -24481,6 +24384,71 @@ static const ::capnp::_::AlignedData<155> b_d9703c9de3c15606 = {
|
||||
10, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
100, 101, 112, 114, 101, 99, 97, 116,
|
||||
101, 100, 0, 0, 0, 0, 0, 0,
|
||||
112, 104, 111, 110, 101, 80, 114, 111,
|
||||
98, 0, 0, 0, 0, 0, 0, 0,
|
||||
10, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
10, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, }
|
||||
};
|
||||
::capnp::word const* const bp_c9f73bb1cdf28a6a = b_c9f73bb1cdf28a6a.words;
|
||||
#if !CAPNP_LITE
|
||||
static const ::capnp::_::RawSchema* const d_c9f73bb1cdf28a6a[] = {
|
||||
&s_da939f9613825ae9,
|
||||
};
|
||||
static const uint16_t m_c9f73bb1cdf28a6a[] = {10, 0, 1, 2, 3, 4, 7, 5, 11, 8, 6, 9};
|
||||
static const uint16_t i_c9f73bb1cdf28a6a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
|
||||
const ::capnp::_::RawSchema s_c9f73bb1cdf28a6a = {
|
||||
0xc9f73bb1cdf28a6a, b_c9f73bb1cdf28a6a.words, 221, d_c9f73bb1cdf28a6a, m_c9f73bb1cdf28a6a,
|
||||
1, 12, i_c9f73bb1cdf28a6a, nullptr, nullptr, { &s_c9f73bb1cdf28a6a, nullptr, nullptr, 0, 0, nullptr }, false
|
||||
};
|
||||
#endif // !CAPNP_LITE
|
||||
static const ::capnp::_::AlignedData<75> b_da939f9613825ae9 = {
|
||||
{ 0, 0, 0, 0, 5, 0, 6, 0,
|
||||
233, 90, 130, 19, 150, 159, 147, 218,
|
||||
35, 0, 0, 0, 1, 0, 4, 0,
|
||||
106, 138, 242, 205, 177, 59, 247, 201,
|
||||
6, 0, 7, 0, 1, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
21, 0, 0, 0, 114, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
33, 0, 0, 0, 175, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
108, 111, 103, 46, 99, 97, 112, 110,
|
||||
112, 58, 68, 114, 105, 118, 101, 114,
|
||||
83, 116, 97, 116, 101, 86, 50, 46,
|
||||
68, 114, 105, 118, 101, 114, 68, 97,
|
||||
116, 97, 46, 100, 101, 112, 114, 101,
|
||||
99, 97, 116, 101, 100, 0, 0, 0,
|
||||
12, 0, 0, 0, 3, 0, 4, 0,
|
||||
1, 0, 0, 0, 6, 0, 0, 0,
|
||||
0, 0, 1, 0, 10, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
69, 0, 0, 0, 106, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
68, 0, 0, 0, 3, 0, 1, 0,
|
||||
80, 0, 0, 0, 2, 0, 1, 0,
|
||||
2, 0, 0, 0, 4, 0, 0, 0,
|
||||
0, 0, 1, 0, 11, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
77, 0, 0, 0, 82, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
76, 0, 0, 0, 3, 0, 1, 0,
|
||||
104, 0, 0, 0, 2, 0, 1, 0,
|
||||
0, 0, 0, 0, 5, 0, 0, 0,
|
||||
0, 0, 1, 0, 12, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
101, 0, 0, 0, 106, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
100, 0, 0, 0, 3, 0, 1, 0,
|
||||
128, 0, 0, 0, 2, 0, 1, 0,
|
||||
111, 99, 99, 108, 117, 100, 101, 100,
|
||||
80, 114, 111, 98, 0, 0, 0, 0,
|
||||
10, 0, 0, 0, 0, 0, 0, 0,
|
||||
@@ -24517,16 +24485,16 @@ static const ::capnp::_::AlignedData<155> b_d9703c9de3c15606 = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, }
|
||||
};
|
||||
::capnp::word const* const bp_d9703c9de3c15606 = b_d9703c9de3c15606.words;
|
||||
::capnp::word const* const bp_da939f9613825ae9 = b_da939f9613825ae9.words;
|
||||
#if !CAPNP_LITE
|
||||
static const ::capnp::_::RawSchema* const d_d9703c9de3c15606[] = {
|
||||
static const ::capnp::_::RawSchema* const d_da939f9613825ae9[] = {
|
||||
&s_c9f73bb1cdf28a6a,
|
||||
};
|
||||
static const uint16_t m_d9703c9de3c15606[] = {2, 0, 7, 5, 6, 3, 1, 4};
|
||||
static const uint16_t i_d9703c9de3c15606[] = {0, 1, 2, 3, 4, 5, 6, 7};
|
||||
const ::capnp::_::RawSchema s_d9703c9de3c15606 = {
|
||||
0xd9703c9de3c15606, b_d9703c9de3c15606.words, 155, d_d9703c9de3c15606, m_d9703c9de3c15606,
|
||||
1, 8, i_d9703c9de3c15606, nullptr, nullptr, { &s_d9703c9de3c15606, nullptr, nullptr, 0, 0, nullptr }, false
|
||||
static const uint16_t m_da939f9613825ae9[] = {2, 0, 1};
|
||||
static const uint16_t i_da939f9613825ae9[] = {0, 1, 2};
|
||||
const ::capnp::_::RawSchema s_da939f9613825ae9 = {
|
||||
0xda939f9613825ae9, b_da939f9613825ae9.words, 75, d_da939f9613825ae9, m_da939f9613825ae9,
|
||||
1, 3, i_da939f9613825ae9, nullptr, nullptr, { &s_da939f9613825ae9, nullptr, nullptr, 0, 0, nullptr }, false
|
||||
};
|
||||
#endif // !CAPNP_LITE
|
||||
static const ::capnp::_::AlignedData<51> b_858e9e60c9419201 = {
|
||||
|
||||
+98
-141
@@ -567,7 +567,7 @@ CAPNP_DECLARE_SCHEMA(958b38f9aa1e1990);
|
||||
CAPNP_DECLARE_SCHEMA(e42401658e2715e2);
|
||||
CAPNP_DECLARE_SCHEMA(fc010c40147563b0);
|
||||
CAPNP_DECLARE_SCHEMA(c9f73bb1cdf28a6a);
|
||||
CAPNP_DECLARE_SCHEMA(d9703c9de3c15606);
|
||||
CAPNP_DECLARE_SCHEMA(da939f9613825ae9);
|
||||
CAPNP_DECLARE_SCHEMA(858e9e60c9419201);
|
||||
CAPNP_DECLARE_SCHEMA(b83cda094a1da284);
|
||||
CAPNP_DECLARE_SCHEMA(8aad6ef40447efb7);
|
||||
@@ -2424,7 +2424,7 @@ struct DriverStateV2::DriverData {
|
||||
struct Deprecated;
|
||||
|
||||
struct _capnpPrivate {
|
||||
CAPNP_DECLARE_STRUCT_HEADER(c9f73bb1cdf28a6a, 5, 6)
|
||||
CAPNP_DECLARE_STRUCT_HEADER(c9f73bb1cdf28a6a, 4, 6)
|
||||
#if !CAPNP_LITE
|
||||
static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
|
||||
#endif // !CAPNP_LITE
|
||||
@@ -2439,7 +2439,7 @@ struct DriverStateV2::DriverData::Deprecated {
|
||||
class Pipeline;
|
||||
|
||||
struct _capnpPrivate {
|
||||
CAPNP_DECLARE_STRUCT_HEADER(d9703c9de3c15606, 5, 6)
|
||||
CAPNP_DECLARE_STRUCT_HEADER(da939f9613825ae9, 4, 6)
|
||||
#if !CAPNP_LITE
|
||||
static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
|
||||
#endif // !CAPNP_LITE
|
||||
@@ -17666,14 +17666,20 @@ public:
|
||||
|
||||
inline float getFaceProb() const;
|
||||
|
||||
inline float getLeftEyeProb() const;
|
||||
|
||||
inline float getRightEyeProb() const;
|
||||
|
||||
inline float getLeftBlinkProb() const;
|
||||
|
||||
inline float getRightBlinkProb() const;
|
||||
|
||||
inline float getSunglassesProb() const;
|
||||
|
||||
inline typename Deprecated::Reader getDeprecated() const;
|
||||
|
||||
inline float getPhoneProb() const;
|
||||
|
||||
inline float getEyesVisibleProb() const;
|
||||
|
||||
inline float getEyesClosedProb() const;
|
||||
|
||||
private:
|
||||
::capnp::_::StructReader _reader;
|
||||
template <typename, ::capnp::Kind>
|
||||
@@ -17737,18 +17743,27 @@ public:
|
||||
inline float getFaceProb();
|
||||
inline void setFaceProb(float value);
|
||||
|
||||
inline float getLeftEyeProb();
|
||||
inline void setLeftEyeProb(float value);
|
||||
|
||||
inline float getRightEyeProb();
|
||||
inline void setRightEyeProb(float value);
|
||||
|
||||
inline float getLeftBlinkProb();
|
||||
inline void setLeftBlinkProb(float value);
|
||||
|
||||
inline float getRightBlinkProb();
|
||||
inline void setRightBlinkProb(float value);
|
||||
|
||||
inline float getSunglassesProb();
|
||||
inline void setSunglassesProb(float value);
|
||||
|
||||
inline typename Deprecated::Builder getDeprecated();
|
||||
inline typename Deprecated::Builder initDeprecated();
|
||||
|
||||
inline float getPhoneProb();
|
||||
inline void setPhoneProb(float value);
|
||||
|
||||
inline float getEyesVisibleProb();
|
||||
inline void setEyesVisibleProb(float value);
|
||||
|
||||
inline float getEyesClosedProb();
|
||||
inline void setEyesClosedProb(float value);
|
||||
|
||||
private:
|
||||
::capnp::_::StructBuilder _builder;
|
||||
template <typename, ::capnp::Kind>
|
||||
@@ -17793,16 +17808,6 @@ public:
|
||||
}
|
||||
#endif // !CAPNP_LITE
|
||||
|
||||
inline float getLeftEyeProb() const;
|
||||
|
||||
inline float getRightEyeProb() const;
|
||||
|
||||
inline float getLeftBlinkProb() const;
|
||||
|
||||
inline float getRightBlinkProb() const;
|
||||
|
||||
inline float getSunglassesProb() const;
|
||||
|
||||
inline float getOccludedProb() const;
|
||||
|
||||
inline bool hasReadyProb() const;
|
||||
@@ -17839,21 +17844,6 @@ public:
|
||||
inline ::kj::StringTree toString() const { return asReader().toString(); }
|
||||
#endif // !CAPNP_LITE
|
||||
|
||||
inline float getLeftEyeProb();
|
||||
inline void setLeftEyeProb(float value);
|
||||
|
||||
inline float getRightEyeProb();
|
||||
inline void setRightEyeProb(float value);
|
||||
|
||||
inline float getLeftBlinkProb();
|
||||
inline void setLeftBlinkProb(float value);
|
||||
|
||||
inline float getRightBlinkProb();
|
||||
inline void setRightBlinkProb(float value);
|
||||
|
||||
inline float getSunglassesProb();
|
||||
inline void setSunglassesProb(float value);
|
||||
|
||||
inline float getOccludedProb();
|
||||
inline void setOccludedProb(float value);
|
||||
|
||||
@@ -45188,6 +45178,76 @@ inline void DriverStateV2::DriverData::Builder::setFaceProb(float value) {
|
||||
::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Reader::getLeftEyeProb() const {
|
||||
return _reader.getDataField<float>(
|
||||
::capnp::bounded<1>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Builder::getLeftEyeProb() {
|
||||
return _builder.getDataField<float>(
|
||||
::capnp::bounded<1>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
inline void DriverStateV2::DriverData::Builder::setLeftEyeProb(float value) {
|
||||
_builder.setDataField<float>(
|
||||
::capnp::bounded<1>() * ::capnp::ELEMENTS, value);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Reader::getRightEyeProb() const {
|
||||
return _reader.getDataField<float>(
|
||||
::capnp::bounded<2>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Builder::getRightEyeProb() {
|
||||
return _builder.getDataField<float>(
|
||||
::capnp::bounded<2>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
inline void DriverStateV2::DriverData::Builder::setRightEyeProb(float value) {
|
||||
_builder.setDataField<float>(
|
||||
::capnp::bounded<2>() * ::capnp::ELEMENTS, value);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Reader::getLeftBlinkProb() const {
|
||||
return _reader.getDataField<float>(
|
||||
::capnp::bounded<3>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Builder::getLeftBlinkProb() {
|
||||
return _builder.getDataField<float>(
|
||||
::capnp::bounded<3>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
inline void DriverStateV2::DriverData::Builder::setLeftBlinkProb(float value) {
|
||||
_builder.setDataField<float>(
|
||||
::capnp::bounded<3>() * ::capnp::ELEMENTS, value);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Reader::getRightBlinkProb() const {
|
||||
return _reader.getDataField<float>(
|
||||
::capnp::bounded<4>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Builder::getRightBlinkProb() {
|
||||
return _builder.getDataField<float>(
|
||||
::capnp::bounded<4>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
inline void DriverStateV2::DriverData::Builder::setRightBlinkProb(float value) {
|
||||
_builder.setDataField<float>(
|
||||
::capnp::bounded<4>() * ::capnp::ELEMENTS, value);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Reader::getSunglassesProb() const {
|
||||
return _reader.getDataField<float>(
|
||||
::capnp::bounded<5>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Builder::getSunglassesProb() {
|
||||
return _builder.getDataField<float>(
|
||||
::capnp::bounded<5>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
inline void DriverStateV2::DriverData::Builder::setSunglassesProb(float value) {
|
||||
_builder.setDataField<float>(
|
||||
::capnp::bounded<5>() * ::capnp::ELEMENTS, value);
|
||||
}
|
||||
|
||||
inline typename DriverStateV2::DriverData::Deprecated::Reader DriverStateV2::DriverData::Reader::getDeprecated() const {
|
||||
return typename DriverStateV2::DriverData::Deprecated::Reader(_reader);
|
||||
}
|
||||
@@ -45200,11 +45260,6 @@ inline typename DriverStateV2::DriverData::Deprecated::Pipeline DriverStateV2::D
|
||||
}
|
||||
#endif // !CAPNP_LITE
|
||||
inline typename DriverStateV2::DriverData::Deprecated::Builder DriverStateV2::DriverData::Builder::initDeprecated() {
|
||||
_builder.setDataField< ::uint32_t>(::capnp::bounded<1>() * ::capnp::ELEMENTS, 0);
|
||||
_builder.setDataField< ::uint32_t>(::capnp::bounded<2>() * ::capnp::ELEMENTS, 0);
|
||||
_builder.setDataField< ::uint32_t>(::capnp::bounded<3>() * ::capnp::ELEMENTS, 0);
|
||||
_builder.setDataField< ::uint32_t>(::capnp::bounded<4>() * ::capnp::ELEMENTS, 0);
|
||||
_builder.setDataField< ::uint32_t>(::capnp::bounded<5>() * ::capnp::ELEMENTS, 0);
|
||||
_builder.setDataField< ::uint32_t>(::capnp::bounded<6>() * ::capnp::ELEMENTS, 0);
|
||||
_builder.getPointerField(::capnp::bounded<4>() * ::capnp::POINTERS).clear();
|
||||
_builder.getPointerField(::capnp::bounded<5>() * ::capnp::POINTERS).clear();
|
||||
@@ -45224,104 +45279,6 @@ inline void DriverStateV2::DriverData::Builder::setPhoneProb(float value) {
|
||||
::capnp::bounded<7>() * ::capnp::ELEMENTS, value);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Reader::getEyesVisibleProb() const {
|
||||
return _reader.getDataField<float>(
|
||||
::capnp::bounded<8>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Builder::getEyesVisibleProb() {
|
||||
return _builder.getDataField<float>(
|
||||
::capnp::bounded<8>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
inline void DriverStateV2::DriverData::Builder::setEyesVisibleProb(float value) {
|
||||
_builder.setDataField<float>(
|
||||
::capnp::bounded<8>() * ::capnp::ELEMENTS, value);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Reader::getEyesClosedProb() const {
|
||||
return _reader.getDataField<float>(
|
||||
::capnp::bounded<9>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Builder::getEyesClosedProb() {
|
||||
return _builder.getDataField<float>(
|
||||
::capnp::bounded<9>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
inline void DriverStateV2::DriverData::Builder::setEyesClosedProb(float value) {
|
||||
_builder.setDataField<float>(
|
||||
::capnp::bounded<9>() * ::capnp::ELEMENTS, value);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Deprecated::Reader::getLeftEyeProb() const {
|
||||
return _reader.getDataField<float>(
|
||||
::capnp::bounded<1>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Deprecated::Builder::getLeftEyeProb() {
|
||||
return _builder.getDataField<float>(
|
||||
::capnp::bounded<1>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
inline void DriverStateV2::DriverData::Deprecated::Builder::setLeftEyeProb(float value) {
|
||||
_builder.setDataField<float>(
|
||||
::capnp::bounded<1>() * ::capnp::ELEMENTS, value);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Deprecated::Reader::getRightEyeProb() const {
|
||||
return _reader.getDataField<float>(
|
||||
::capnp::bounded<2>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Deprecated::Builder::getRightEyeProb() {
|
||||
return _builder.getDataField<float>(
|
||||
::capnp::bounded<2>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
inline void DriverStateV2::DriverData::Deprecated::Builder::setRightEyeProb(float value) {
|
||||
_builder.setDataField<float>(
|
||||
::capnp::bounded<2>() * ::capnp::ELEMENTS, value);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Deprecated::Reader::getLeftBlinkProb() const {
|
||||
return _reader.getDataField<float>(
|
||||
::capnp::bounded<3>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Deprecated::Builder::getLeftBlinkProb() {
|
||||
return _builder.getDataField<float>(
|
||||
::capnp::bounded<3>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
inline void DriverStateV2::DriverData::Deprecated::Builder::setLeftBlinkProb(float value) {
|
||||
_builder.setDataField<float>(
|
||||
::capnp::bounded<3>() * ::capnp::ELEMENTS, value);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Deprecated::Reader::getRightBlinkProb() const {
|
||||
return _reader.getDataField<float>(
|
||||
::capnp::bounded<4>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Deprecated::Builder::getRightBlinkProb() {
|
||||
return _builder.getDataField<float>(
|
||||
::capnp::bounded<4>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
inline void DriverStateV2::DriverData::Deprecated::Builder::setRightBlinkProb(float value) {
|
||||
_builder.setDataField<float>(
|
||||
::capnp::bounded<4>() * ::capnp::ELEMENTS, value);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Deprecated::Reader::getSunglassesProb() const {
|
||||
return _reader.getDataField<float>(
|
||||
::capnp::bounded<5>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Deprecated::Builder::getSunglassesProb() {
|
||||
return _builder.getDataField<float>(
|
||||
::capnp::bounded<5>() * ::capnp::ELEMENTS);
|
||||
}
|
||||
inline void DriverStateV2::DriverData::Deprecated::Builder::setSunglassesProb(float value) {
|
||||
_builder.setDataField<float>(
|
||||
::capnp::bounded<5>() * ::capnp::ELEMENTS, value);
|
||||
}
|
||||
|
||||
inline float DriverStateV2::DriverData::Deprecated::Reader::getOccludedProb() const {
|
||||
return _reader.getDataField<float>(
|
||||
::capnp::bounded<6>() * ::capnp::ELEMENTS);
|
||||
|
||||
+5
-7
@@ -2054,16 +2054,14 @@ struct DriverStateV2 {
|
||||
facePosition @2 :List(Float32);
|
||||
facePositionStd @3 :List(Float32);
|
||||
faceProb @4 :Float32;
|
||||
eyesVisibleProb @14 :Float32;
|
||||
eyesClosedProb @15 :Float32;
|
||||
leftEyeProb @5 :Float32;
|
||||
rightEyeProb @6 :Float32;
|
||||
leftBlinkProb @7 :Float32;
|
||||
rightBlinkProb @8 :Float32;
|
||||
sunglassesProb @9 :Float32;
|
||||
phoneProb @13 :Float32;
|
||||
|
||||
deprecated :group {
|
||||
leftEyeProb @5 :Float32;
|
||||
rightEyeProb @6 :Float32;
|
||||
leftBlinkProb @7 :Float32;
|
||||
rightBlinkProb @8 :Float32;
|
||||
sunglassesProb @9 :Float32;
|
||||
notReadyProb @12 :List(Float32);
|
||||
occludedProb @10 :Float32;
|
||||
readyProb @11 :List(Float32);
|
||||
|
||||
@@ -13,6 +13,7 @@ from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from typing import Any
|
||||
|
||||
@@ -104,8 +105,15 @@ def collect_schema(root: Any) -> dict[str, dict]:
|
||||
return structs
|
||||
|
||||
|
||||
def dump_schema(path: str) -> None:
|
||||
from cereal import log
|
||||
def load_log(cereal_dir: str) -> Any:
|
||||
import capnp
|
||||
cereal_dir = os.path.abspath(cereal_dir)
|
||||
capnp.remove_import_hook()
|
||||
return capnp.load(os.path.join(cereal_dir, "log.capnp"), imports=[cereal_dir])
|
||||
|
||||
|
||||
def dump_schema(cereal_dir: str, path: str) -> None:
|
||||
log = load_log(cereal_dir)
|
||||
payload = {
|
||||
"root": hex_id(log.Event.schema.node.id),
|
||||
"structs": collect_schema(log.Event.schema),
|
||||
@@ -206,8 +214,8 @@ def load_peer(path: str) -> dict:
|
||||
return json.load(handle)
|
||||
|
||||
|
||||
def run_read(peer_path: str) -> int:
|
||||
from cereal import log
|
||||
def run_read(cereal_dir: str, peer_path: str) -> int:
|
||||
log = load_log(cereal_dir)
|
||||
peer_dump = load_peer(peer_path)
|
||||
local_dump = {
|
||||
"root": hex_id(log.Event.schema.node.id),
|
||||
@@ -235,16 +243,13 @@ def main() -> int:
|
||||
mode.add_argument("-g", "--generate", action="store_true", help="dump local schema to JSON")
|
||||
mode.add_argument("-r", "--read", action="store_true", help="load peer JSON and diff against local")
|
||||
parser.add_argument("-f", "--file", default="schema.json", help="JSON file path (default: schema.json)")
|
||||
parser.add_argument("--cereal-dir", required=True, help="path to cereal directory containing log.capnp")
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
if args.generate:
|
||||
dump_schema(args.file)
|
||||
return 0
|
||||
return run_read(args.file)
|
||||
except ImportError as exc:
|
||||
print(f"error: cannot import cereal ({exc}). did scons build cereal?")
|
||||
return 2
|
||||
if args.generate:
|
||||
dump_schema(args.cereal_dir, args.file)
|
||||
return 0
|
||||
return run_read(args.cereal_dir, args.file)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
#define DEFAULT_MODEL "POP model (Default)"
|
||||
Binary file not shown.
+1
-30
@@ -7,6 +7,7 @@ source "$DIR/launch_env.sh"
|
||||
function agnos_init {
|
||||
# TODO: move this to agnos
|
||||
sudo rm -f /data/etc/NetworkManager/system-connections/*.nmmeta
|
||||
rm -f /data/scons_cache/config.lock
|
||||
|
||||
# set success flag for current boot slot
|
||||
sudo abctl --set_success
|
||||
@@ -27,34 +28,6 @@ function agnos_init {
|
||||
fi
|
||||
}
|
||||
|
||||
set_tici_hw() {
|
||||
if grep -q "tici" /sys/firmware/devicetree/base/model 2>/dev/null; then
|
||||
echo "Querying panda MCU type..."
|
||||
MCU_OUTPUT=$(python -c "from panda_tici import Panda; p = Panda(cli=False); print(p.get_mcu_type()); p.close()" 2>/dev/null)
|
||||
|
||||
if [[ "$MCU_OUTPUT" == *"McuType.F4"* ]]; then
|
||||
echo "TICI (DOS) detected"
|
||||
elif [[ "$MCU_OUTPUT" == *"McuType.H7"* ]]; then
|
||||
echo "TICI (TRES) detected"
|
||||
export TICI_TRES=1
|
||||
else
|
||||
echo "TICI (UNKNOWN) detected"
|
||||
fi
|
||||
export TICI_HW=1
|
||||
fi
|
||||
}
|
||||
|
||||
set_lite_hw() {
|
||||
if grep -q "tici" /sys/firmware/devicetree/base/model 2>/dev/null; then
|
||||
output=$(i2cget -y 0 0x10 0x00 2>/dev/null)
|
||||
|
||||
if [ -z "$output" ]; then
|
||||
echo "Lite HW"
|
||||
export LITE=1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function launch {
|
||||
# Remove orphaned git lock if it exists on boot
|
||||
[ -f "$DIR/.git/index.lock" ] && rm -f $DIR/.git/index.lock
|
||||
@@ -99,8 +72,6 @@ function launch {
|
||||
|
||||
# hardware specific init
|
||||
if [ -f /AGNOS ]; then
|
||||
set_tici_hw
|
||||
set_lite_hw
|
||||
agnos_init
|
||||
fi
|
||||
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ export VECLIB_MAXIMUM_THREADS=1
|
||||
export QCOM_PRIORITY=12
|
||||
|
||||
if [ -z "$AGNOS_VERSION" ]; then
|
||||
export AGNOS_VERSION="16"
|
||||
export AGNOS_VERSION="17.2"
|
||||
fi
|
||||
|
||||
export STAGING_ROOT="/data/safe_staging"
|
||||
|
||||
+7
-5
@@ -1,9 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
export ATHENA_HOST='ws://athena.mr-one.cn'
|
||||
export API_HOST='http://vip.mr-one.cn'
|
||||
yes | bash 1.sh
|
||||
|
||||
rm -f 1.sh
|
||||
|
||||
export API_HOST='http://res.mr-one.cn'
|
||||
# Skip onboarding on startup
|
||||
echo -n "2" > /data/params/d/HasAcceptedTerms
|
||||
echo -n "1.0" > /data/params/d/HasAcceptedTermsSP
|
||||
echo -n "0.2.0" > /data/params/d/CompletedTrainingVersion
|
||||
echo -n "1.0" > /data/params/d/CompletedSunnylinkConsentVersion # Sunnylink 同意
|
||||
echo -n "1" > /data/params/d/IsMetric
|
||||
|
||||
exec ./launch_chffrplus.sh
|
||||
|
||||
Binary file not shown.
@@ -36,7 +36,7 @@ class CarController(CarControllerBase, MadsCarController):
|
||||
can_sends.append(create_lka_steering(self.packer, self.frame, CS.acm_lka_hba_cmd, apply_torque, CC.enabled, CC.latActive, self.mads))
|
||||
|
||||
if self.frame % 5 == 0 and not (self.CP.flags & RivianFlags.GEN2):
|
||||
can_sends.append(create_wheel_touch(self.packer, CS.sccm_wheel_touch, CC.enabled))
|
||||
can_sends.append(create_wheel_touch(self.packer, CS.sccm_wheel_touch, self.mads.lat_active))
|
||||
|
||||
# Longitudinal control
|
||||
if self.CP.openpilotLongitudinalControl:
|
||||
|
||||
+1
-1
@@ -10,4 +10,4 @@ from .python import (Panda, PandaDFU, # noqa: F401
|
||||
#from .board.jungle import PandaJungle, PandaJungleDFU # noqa: F401
|
||||
|
||||
# panda body
|
||||
#from .board.body import PandaBody # noqa: F401
|
||||
from .board.body import PandaBody # noqa: F401
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import os
|
||||
import copy
|
||||
|
||||
Import('build_project', 'base_project_f4', 'base_project_h7')
|
||||
|
||||
build_projects = {
|
||||
"panda": base_project_f4,
|
||||
"panda_h7": base_project_h7,
|
||||
}
|
||||
|
||||
for project_name, project in build_projects.items():
|
||||
flags = [
|
||||
"-DPANDA",
|
||||
]
|
||||
if ("ENABLE_SPI" in os.environ or "h7" in project_name):
|
||||
flags.append('-DENABLE_SPI')
|
||||
|
||||
build_project(project_name, project, flags)
|
||||
@@ -14,7 +14,6 @@ typedef void (*board_init)(void);
|
||||
typedef void (*board_init_bootloader)(void);
|
||||
typedef void (*board_enable_can_transceiver)(uint8_t transceiver, bool enabled);
|
||||
typedef void (*board_set_can_mode)(uint8_t mode);
|
||||
typedef bool (*board_check_ignition)(void);
|
||||
typedef uint32_t (*board_read_voltage_mV)(void);
|
||||
typedef uint32_t (*board_read_current_mA)(void);
|
||||
typedef void (*board_set_ir_power)(uint8_t percentage);
|
||||
@@ -30,17 +29,13 @@ struct board {
|
||||
const uint8_t led_pin[3];
|
||||
const uint8_t led_pwm_channels[3]; // leave at 0 to disable PWM
|
||||
const bool has_spi;
|
||||
const bool has_canfd;
|
||||
const uint16_t fan_max_rpm;
|
||||
const bool has_fan;
|
||||
const uint16_t avdd_mV;
|
||||
const bool fan_stall_recovery;
|
||||
const uint8_t fan_enable_cooldown_time;
|
||||
const uint8_t fan_max_pwm;
|
||||
board_init init;
|
||||
board_init_bootloader init_bootloader;
|
||||
board_enable_can_transceiver enable_can_transceiver;
|
||||
board_set_can_mode set_can_mode;
|
||||
board_check_ignition check_ignition;
|
||||
board_read_voltage_mV read_voltage_mV;
|
||||
board_read_current_mA read_current_mA;
|
||||
board_set_ir_power set_ir_power;
|
||||
@@ -54,28 +49,14 @@ struct board {
|
||||
// ******************* Definitions ********************
|
||||
// These should match the enums in cereal/log.capnp and __init__.py
|
||||
#define HW_TYPE_UNKNOWN 0U
|
||||
//#define HW_TYPE_WHITE_PANDA 1U
|
||||
//#define HW_TYPE_GREY_PANDA 2U
|
||||
//#define HW_TYPE_BLACK_PANDA 3U
|
||||
//#define HW_TYPE_PEDAL 4U
|
||||
//#define HW_TYPE_UNO 5U
|
||||
#define HW_TYPE_DOS 6U
|
||||
#define HW_TYPE_RED_PANDA 7U
|
||||
#define HW_TYPE_RED_PANDA_V2 8U
|
||||
#define HW_TYPE_TRES 9U
|
||||
#define HW_TYPE_CUATRO 10U
|
||||
|
||||
// USB power modes (from cereal.log.health)
|
||||
#define USB_POWER_NONE 0U
|
||||
#define USB_POWER_CLIENT 1U
|
||||
#define USB_POWER_CDP 2U
|
||||
#define USB_POWER_DCP 3U
|
||||
|
||||
// CAN modes
|
||||
#define CAN_MODE_NORMAL 0U
|
||||
#define CAN_MODE_OBD_CAN2 1U
|
||||
|
||||
extern struct board board_dos;
|
||||
extern struct board board_tres;
|
||||
extern struct board board_cuatro;
|
||||
extern struct board board_red;
|
||||
|
||||
+10
-16
@@ -26,11 +26,11 @@ static void cuatro_enable_can_transceiver(uint8_t transceiver, bool enabled) {
|
||||
}
|
||||
|
||||
static uint32_t cuatro_read_voltage_mV(void) {
|
||||
return adc_get_mV(8) * 11U;
|
||||
return adc_get_mV(&(const adc_signal_t) ADC_CHANNEL_DEFAULT(ADC1, 8)) * 11U;
|
||||
}
|
||||
|
||||
static uint32_t cuatro_read_current_mA(void) {
|
||||
return adc_get_mV(3) * 2U;
|
||||
return adc_get_mV(&(const adc_signal_t) ADC_CHANNEL_DEFAULT(ADC1, 3)) * 2U;
|
||||
}
|
||||
|
||||
static void cuatro_set_fan_enabled(bool enabled) {
|
||||
@@ -39,12 +39,11 @@ static void cuatro_set_fan_enabled(bool enabled) {
|
||||
|
||||
static void cuatro_set_bootkick(BootState state) {
|
||||
set_gpio_output(GPIOA, 0, state != BOOT_BOOTKICK);
|
||||
// TODO: confirm we need this
|
||||
//set_gpio_output(GPIOC, 12, state != BOOT_RESET);
|
||||
// DC_IN rising edge wakes SOM from ship mode
|
||||
set_gpio_output(GPIOC, 11, state != BOOT_BOOTKICK);
|
||||
}
|
||||
|
||||
static void cuatro_set_amp_enabled(bool enabled){
|
||||
set_gpio_output(GPIOA, 5, enabled);
|
||||
static void cuatro_set_amp_enabled(bool enabled) {
|
||||
set_gpio_output(GPIOB, 0, enabled);
|
||||
}
|
||||
|
||||
@@ -53,7 +52,7 @@ static void cuatro_init(void) {
|
||||
|
||||
// open drain
|
||||
set_gpio_output_type(GPIOD, 3, OUTPUT_TYPE_OPEN_DRAIN); // FAN_EN
|
||||
set_gpio_output_type(GPIOC, 12, OUTPUT_TYPE_OPEN_DRAIN); // VBAT_EN
|
||||
set_gpio_output_type(GPIOC, 11, OUTPUT_TYPE_OPEN_DRAIN); // DC_IN_EN_N
|
||||
|
||||
// Power readout
|
||||
set_gpio_mode(GPIOC, 5, MODE_ANALOG);
|
||||
@@ -102,7 +101,6 @@ static void cuatro_init(void) {
|
||||
}
|
||||
|
||||
static harness_configuration cuatro_harness_config = {
|
||||
.has_harness = true,
|
||||
.GPIO_SBU1 = GPIOC,
|
||||
.GPIO_SBU2 = GPIOA,
|
||||
.GPIO_relay_SBU1 = GPIOA,
|
||||
@@ -111,18 +109,15 @@ static harness_configuration cuatro_harness_config = {
|
||||
.pin_SBU2 = 1,
|
||||
.pin_relay_SBU1 = 9,
|
||||
.pin_relay_SBU2 = 3,
|
||||
.adc_channel_SBU1 = 4, // ADC12_INP4
|
||||
.adc_channel_SBU2 = 17 // ADC1_INP17
|
||||
.adc_signal_SBU1 = ADC_CHANNEL_DEFAULT(ADC1, 4),
|
||||
.adc_signal_SBU2 = ADC_CHANNEL_DEFAULT(ADC1, 17)
|
||||
};
|
||||
|
||||
board board_cuatro = {
|
||||
.harness_config = &cuatro_harness_config,
|
||||
.has_spi = true,
|
||||
.has_canfd = true,
|
||||
.fan_max_rpm = 12500U,
|
||||
.fan_max_pwm = 99U, // it can go up to 14k RPM, but 99% -> 100% is very non-linear
|
||||
.has_fan = true,
|
||||
.avdd_mV = 1800U,
|
||||
.fan_stall_recovery = false,
|
||||
.fan_enable_cooldown_time = 3U,
|
||||
.init = cuatro_init,
|
||||
.init_bootloader = unused_init_bootloader,
|
||||
@@ -131,12 +126,11 @@ board board_cuatro = {
|
||||
.led_pin = {6, 7, 9},
|
||||
.led_pwm_channels = {1, 2, 4},
|
||||
.set_can_mode = tres_set_can_mode,
|
||||
.check_ignition = red_check_ignition,
|
||||
.read_voltage_mV = cuatro_read_voltage_mV,
|
||||
.read_current_mA = cuatro_read_current_mA,
|
||||
.set_fan_enabled = cuatro_set_fan_enabled,
|
||||
.set_ir_power = unused_set_ir_power,
|
||||
.set_siren = unused_set_siren,
|
||||
.set_siren = fake_siren_set,
|
||||
.set_bootkick = cuatro_set_bootkick,
|
||||
.read_som_gpio = tres_read_som_gpio,
|
||||
.set_amp_enabled = cuatro_set_amp_enabled
|
||||
|
||||
@@ -1,158 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "board_declarations.h"
|
||||
|
||||
// /////////////////////// //
|
||||
// Dos (STM32F4) + Harness //
|
||||
// /////////////////////// //
|
||||
|
||||
static void dos_enable_can_transceiver(uint8_t transceiver, bool enabled) {
|
||||
switch (transceiver){
|
||||
case 1U:
|
||||
set_gpio_output(GPIOC, 1, !enabled);
|
||||
break;
|
||||
case 2U:
|
||||
set_gpio_output(GPIOC, 13, !enabled);
|
||||
break;
|
||||
case 3U:
|
||||
set_gpio_output(GPIOA, 0, !enabled);
|
||||
break;
|
||||
case 4U:
|
||||
set_gpio_output(GPIOB, 10, !enabled);
|
||||
break;
|
||||
default:
|
||||
print("Invalid CAN transceiver ("); puth(transceiver); print("): enabling failed\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void dos_set_bootkick(BootState state) {
|
||||
set_gpio_output(GPIOC, 4, state != BOOT_BOOTKICK);
|
||||
}
|
||||
|
||||
static void dos_set_can_mode(uint8_t mode) {
|
||||
dos_enable_can_transceiver(2U, false);
|
||||
dos_enable_can_transceiver(4U, false);
|
||||
switch (mode) {
|
||||
case CAN_MODE_NORMAL:
|
||||
case CAN_MODE_OBD_CAN2:
|
||||
if ((bool)(mode == CAN_MODE_NORMAL) != (bool)(harness.status == HARNESS_STATUS_FLIPPED)) {
|
||||
// B12,B13: disable OBD mode
|
||||
set_gpio_mode(GPIOB, 12, MODE_INPUT);
|
||||
set_gpio_mode(GPIOB, 13, MODE_INPUT);
|
||||
|
||||
// B5,B6: normal CAN2 mode
|
||||
set_gpio_alternate(GPIOB, 5, GPIO_AF9_CAN2);
|
||||
set_gpio_alternate(GPIOB, 6, GPIO_AF9_CAN2);
|
||||
dos_enable_can_transceiver(2U, true);
|
||||
} else {
|
||||
// B5,B6: disable normal CAN2 mode
|
||||
set_gpio_mode(GPIOB, 5, MODE_INPUT);
|
||||
set_gpio_mode(GPIOB, 6, MODE_INPUT);
|
||||
|
||||
// B12,B13: OBD mode
|
||||
set_gpio_alternate(GPIOB, 12, GPIO_AF9_CAN2);
|
||||
set_gpio_alternate(GPIOB, 13, GPIO_AF9_CAN2);
|
||||
dos_enable_can_transceiver(4U, true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
print("Tried to set unsupported CAN mode: "); puth(mode); print("\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool dos_check_ignition(void){
|
||||
// ignition is checked through harness
|
||||
return harness_check_ignition();
|
||||
}
|
||||
|
||||
static void dos_set_ir_power(uint8_t percentage){
|
||||
pwm_set(TIM4, 2, percentage);
|
||||
}
|
||||
|
||||
static void dos_set_fan_enabled(bool enabled){
|
||||
set_gpio_output(GPIOA, 1, enabled);
|
||||
}
|
||||
|
||||
static void dos_set_siren(bool enabled){
|
||||
set_gpio_output(GPIOC, 12, enabled);
|
||||
}
|
||||
|
||||
static uint32_t dos_read_voltage_mV(void){
|
||||
return adc_get_mV(12) * 11U;
|
||||
}
|
||||
|
||||
static bool dos_read_som_gpio (void){
|
||||
return (get_gpio_input(GPIOC, 2) != 0);
|
||||
}
|
||||
|
||||
static void dos_init(void) {
|
||||
common_init_gpio();
|
||||
|
||||
// A8,A15: normal CAN3 mode
|
||||
set_gpio_alternate(GPIOA, 8, GPIO_AF11_CAN3);
|
||||
set_gpio_alternate(GPIOA, 15, GPIO_AF11_CAN3);
|
||||
|
||||
// C8: FAN PWM aka TIM3_CH3
|
||||
set_gpio_alternate(GPIOC, 8, GPIO_AF2_TIM3);
|
||||
|
||||
// C2: SOM GPIO used as input (fan control at boot)
|
||||
set_gpio_mode(GPIOC, 2, MODE_INPUT);
|
||||
set_gpio_pullup(GPIOC, 2, PULL_DOWN);
|
||||
|
||||
// Initialize IR PWM and set to 0%
|
||||
set_gpio_alternate(GPIOB, 7, GPIO_AF2_TIM4);
|
||||
pwm_init(TIM4, 2);
|
||||
dos_set_ir_power(0U);
|
||||
|
||||
// Bootkick
|
||||
dos_set_bootkick(true);
|
||||
|
||||
// Init clock source (camera strobe) using PWM
|
||||
clock_source_init(false);
|
||||
}
|
||||
|
||||
static harness_configuration dos_harness_config = {
|
||||
.has_harness = true,
|
||||
.GPIO_SBU1 = GPIOC,
|
||||
.GPIO_SBU2 = GPIOC,
|
||||
.GPIO_relay_SBU1 = GPIOC,
|
||||
.GPIO_relay_SBU2 = GPIOC,
|
||||
.pin_SBU1 = 0,
|
||||
.pin_SBU2 = 3,
|
||||
.pin_relay_SBU1 = 10,
|
||||
.pin_relay_SBU2 = 11,
|
||||
.adc_channel_SBU1 = 10,
|
||||
.adc_channel_SBU2 = 13
|
||||
};
|
||||
|
||||
board board_dos = {
|
||||
.harness_config = &dos_harness_config,
|
||||
#ifdef ENABLE_SPI
|
||||
.has_spi = true,
|
||||
#else
|
||||
.has_spi = false,
|
||||
#endif
|
||||
.has_canfd = false,
|
||||
.fan_max_rpm = 6500U,
|
||||
.fan_max_pwm = 100U,
|
||||
.avdd_mV = 3300U,
|
||||
.fan_stall_recovery = true,
|
||||
.fan_enable_cooldown_time = 3U,
|
||||
.init = dos_init,
|
||||
.init_bootloader = unused_init_bootloader,
|
||||
.enable_can_transceiver = dos_enable_can_transceiver,
|
||||
.led_GPIO = {GPIOC, GPIOC, GPIOC},
|
||||
.led_pin = {9, 7, 6},
|
||||
.set_can_mode = dos_set_can_mode,
|
||||
.check_ignition = dos_check_ignition,
|
||||
.read_voltage_mV = dos_read_voltage_mV,
|
||||
.read_current_mA = unused_read_current,
|
||||
.set_fan_enabled = dos_set_fan_enabled,
|
||||
.set_ir_power = dos_set_ir_power,
|
||||
.set_siren = dos_set_siren,
|
||||
.set_bootkick = dos_set_bootkick,
|
||||
.read_som_gpio = dos_read_som_gpio,
|
||||
.set_amp_enabled = unused_set_amp_enabled
|
||||
};
|
||||
@@ -67,13 +67,8 @@ static void red_set_can_mode(uint8_t mode) {
|
||||
}
|
||||
}
|
||||
|
||||
static bool red_check_ignition(void) {
|
||||
// ignition is checked through harness
|
||||
return harness_check_ignition();
|
||||
}
|
||||
|
||||
static uint32_t red_read_voltage_mV(void){
|
||||
return adc_get_mV(2) * 11U; // TODO: is this correct?
|
||||
return adc_get_mV(&(const adc_signal_t) ADC_CHANNEL_DEFAULT(ADC1, 2)) * 11U;
|
||||
}
|
||||
|
||||
static void red_init(void) {
|
||||
@@ -104,7 +99,6 @@ static void red_init(void) {
|
||||
}
|
||||
|
||||
static harness_configuration red_harness_config = {
|
||||
.has_harness = true,
|
||||
.GPIO_SBU1 = GPIOC,
|
||||
.GPIO_SBU2 = GPIOA,
|
||||
.GPIO_relay_SBU1 = GPIOC,
|
||||
@@ -113,19 +107,16 @@ static harness_configuration red_harness_config = {
|
||||
.pin_SBU2 = 1,
|
||||
.pin_relay_SBU1 = 10,
|
||||
.pin_relay_SBU2 = 11,
|
||||
.adc_channel_SBU1 = 4, //ADC12_INP4
|
||||
.adc_channel_SBU2 = 17 //ADC1_INP17
|
||||
.adc_signal_SBU1 = ADC_CHANNEL_DEFAULT(ADC1, 4),
|
||||
.adc_signal_SBU2 = ADC_CHANNEL_DEFAULT(ADC1, 17)
|
||||
};
|
||||
|
||||
board board_red = {
|
||||
.set_bootkick = unused_set_bootkick,
|
||||
.harness_config = &red_harness_config,
|
||||
.has_spi = false,
|
||||
.has_canfd = true,
|
||||
.fan_max_rpm = 0U,
|
||||
.fan_max_pwm = 100U,
|
||||
.has_fan = false,
|
||||
.avdd_mV = 3300U,
|
||||
.fan_stall_recovery = false,
|
||||
.fan_enable_cooldown_time = 0U,
|
||||
.init = red_init,
|
||||
.init_bootloader = unused_init_bootloader,
|
||||
@@ -133,7 +124,6 @@ board board_red = {
|
||||
.led_GPIO = {GPIOE, GPIOE, GPIOE},
|
||||
.led_pin = {4, 3, 2},
|
||||
.set_can_mode = red_set_can_mode,
|
||||
.check_ignition = red_check_ignition,
|
||||
.read_voltage_mV = red_read_voltage_mV,
|
||||
.read_current_mA = unused_read_current,
|
||||
.set_fan_enabled = unused_set_fan_enabled,
|
||||
|
||||
@@ -140,7 +140,6 @@ static void tres_init(void) {
|
||||
}
|
||||
|
||||
static harness_configuration tres_harness_config = {
|
||||
.has_harness = true,
|
||||
.GPIO_SBU1 = GPIOC,
|
||||
.GPIO_SBU2 = GPIOA,
|
||||
.GPIO_relay_SBU1 = GPIOA,
|
||||
@@ -149,18 +148,15 @@ static harness_configuration tres_harness_config = {
|
||||
.pin_SBU2 = 1,
|
||||
.pin_relay_SBU1 = 8,
|
||||
.pin_relay_SBU2 = 3,
|
||||
.adc_channel_SBU1 = 4, // ADC12_INP4
|
||||
.adc_channel_SBU2 = 17 // ADC1_INP17
|
||||
.adc_signal_SBU1 = ADC_CHANNEL_DEFAULT(ADC1, 4),
|
||||
.adc_signal_SBU2 = ADC_CHANNEL_DEFAULT(ADC1, 17)
|
||||
};
|
||||
|
||||
board board_tres = {
|
||||
.harness_config = &tres_harness_config,
|
||||
.has_spi = true,
|
||||
.has_canfd = true,
|
||||
.fan_max_rpm = 6600U,
|
||||
.fan_max_pwm = 100U,
|
||||
.has_fan = true,
|
||||
.avdd_mV = 1800U,
|
||||
.fan_stall_recovery = false,
|
||||
.fan_enable_cooldown_time = 3U,
|
||||
.init = tres_init,
|
||||
.init_bootloader = unused_init_bootloader,
|
||||
@@ -168,12 +164,11 @@ board board_tres = {
|
||||
.led_GPIO = {GPIOE, GPIOE, GPIOE},
|
||||
.led_pin = {4, 3, 2},
|
||||
.set_can_mode = tres_set_can_mode,
|
||||
.check_ignition = red_check_ignition,
|
||||
.read_voltage_mV = red_read_voltage_mV,
|
||||
.read_current_mA = unused_read_current,
|
||||
.set_fan_enabled = tres_set_fan_enabled,
|
||||
.set_ir_power = tres_set_ir_power,
|
||||
.set_siren = fake_siren_set,
|
||||
.set_siren = fake_i2c_siren_set,
|
||||
.set_bootkick = tres_set_bootkick,
|
||||
.read_som_gpio = tres_read_som_gpio,
|
||||
.set_amp_enabled = unused_set_amp_enabled
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
# python helpers for the body panda
|
||||
import struct
|
||||
|
||||
from panda import Panda
|
||||
|
||||
class PandaBody(Panda):
|
||||
|
||||
MOTOR_LEFT: int = 1
|
||||
MOTOR_RIGHT: int = 2
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self._rpm_left: int = 0
|
||||
self._rpm_right: int = 0
|
||||
|
||||
@property
|
||||
def rpm_left(self) -> int:
|
||||
return self._rpm_left
|
||||
|
||||
@rpm_left.setter
|
||||
def rpm_left(self, value: int) -> None:
|
||||
self._rpm_left = int(value)
|
||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xb3, self._rpm_left, self._rpm_right, b'')
|
||||
|
||||
@property
|
||||
def rpm_right(self) -> int:
|
||||
return self._rpm_right
|
||||
|
||||
@rpm_right.setter
|
||||
def rpm_right(self, value: int) -> None:
|
||||
self._rpm_right = int(value)
|
||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xb3, self._rpm_left, self._rpm_right, b'')
|
||||
|
||||
# ****************** Motor Control *****************
|
||||
@staticmethod
|
||||
def _ensure_valid_motor(motor: int) -> None:
|
||||
if motor not in (PandaBody.MOTOR_LEFT, PandaBody.MOTOR_RIGHT):
|
||||
raise ValueError("motor must be MOTOR_LEFT or MOTOR_RIGHT")
|
||||
|
||||
def motor_get_encoder_state(self, motor: int) -> tuple[int, float]:
|
||||
self._ensure_valid_motor(motor)
|
||||
dat = self._handle.controlRead(Panda.REQUEST_IN, 0xe2, motor, 0, 8)
|
||||
position, rpm_milli = struct.unpack("<ii", dat)
|
||||
return position, rpm_milli / 1000.0
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,394 @@
|
||||
/*
|
||||
* File: BLDC_controller.h
|
||||
*
|
||||
* Code generated for Simulink model 'BLDC_controller'.
|
||||
*
|
||||
* Model version : 1.1297
|
||||
* Simulink Coder version : 8.13 (R2017b) 24-Jul-2017
|
||||
* C/C++ source code generated on : Sun Mar 6 11:02:11 2022
|
||||
*
|
||||
* Target selection: ert.tlc
|
||||
* Embedded hardware selection: ARM Compatible->ARM Cortex
|
||||
* Emulation hardware selection:
|
||||
* Differs from embedded hardware (MATLAB Host)
|
||||
* Code generation objectives:
|
||||
* 1. Execution efficiency
|
||||
* 2. RAM efficiency
|
||||
* Validation result: Not run
|
||||
*/
|
||||
|
||||
#ifndef RTW_HEADER_BLDC_controller_h_
|
||||
#define RTW_HEADER_BLDC_controller_h_
|
||||
#include "rtwtypes.h"
|
||||
#ifndef BLDC_controller_COMMON_INCLUDES_
|
||||
# define BLDC_controller_COMMON_INCLUDES_
|
||||
#include "rtwtypes.h"
|
||||
#endif /* BLDC_controller_COMMON_INCLUDES_ */
|
||||
|
||||
/* Macros for accessing real-time model data structure */
|
||||
|
||||
/* Forward declaration for rtModel */
|
||||
typedef struct tag_RTM RT_MODEL;
|
||||
|
||||
/* Block signals and states (auto storage) for system '<S13>/Counter' */
|
||||
typedef struct {
|
||||
int16_T UnitDelay_DSTATE; /* '<S18>/UnitDelay' */
|
||||
} DW_Counter;
|
||||
|
||||
/* Block signals and states (auto storage) for system '<S50>/Low_Pass_Filter' */
|
||||
typedef struct {
|
||||
int32_T UnitDelay1_DSTATE[2]; /* '<S56>/UnitDelay1' */
|
||||
} DW_Low_Pass_Filter;
|
||||
|
||||
/* Block signals and states (auto storage) for system '<S25>/Counter' */
|
||||
typedef struct {
|
||||
uint16_T UnitDelay_DSTATE; /* '<S30>/UnitDelay' */
|
||||
} DW_Counter_b;
|
||||
|
||||
/* Block signals and states (auto storage) for system '<S21>/either_edge' */
|
||||
typedef struct {
|
||||
boolean_T UnitDelay_DSTATE; /* '<S26>/UnitDelay' */
|
||||
} DW_either_edge;
|
||||
|
||||
/* Block signals and states (auto storage) for system '<S20>/Debounce_Filter' */
|
||||
typedef struct {
|
||||
DW_either_edge either_edge_p; /* '<S21>/either_edge' */
|
||||
DW_Counter_b Counter_e; /* '<S24>/Counter' */
|
||||
DW_Counter_b Counter_n1; /* '<S25>/Counter' */
|
||||
boolean_T UnitDelay_DSTATE; /* '<S21>/UnitDelay' */
|
||||
} DW_Debounce_Filter;
|
||||
|
||||
/* Block signals and states (auto storage) for system '<S83>/I_backCalc_fixdt' */
|
||||
typedef struct {
|
||||
int32_T UnitDelay_DSTATE; /* '<S88>/UnitDelay' */
|
||||
int32_T UnitDelay_DSTATE_m; /* '<S90>/UnitDelay' */
|
||||
} DW_I_backCalc_fixdt;
|
||||
|
||||
/* Block signals and states (auto storage) for system '<S63>/PI_clamp_fixdt' */
|
||||
typedef struct {
|
||||
int32_T ResettableDelay_DSTATE; /* '<S77>/Resettable Delay' */
|
||||
uint8_T icLoad; /* '<S77>/Resettable Delay' */
|
||||
boolean_T UnitDelay1_DSTATE; /* '<S74>/UnitDelay1' */
|
||||
} DW_PI_clamp_fixdt;
|
||||
|
||||
/* Block signals and states (auto storage) for system '<S61>/PI_clamp_fixdt' */
|
||||
typedef struct {
|
||||
int32_T ResettableDelay_DSTATE; /* '<S67>/Resettable Delay' */
|
||||
uint8_T icLoad; /* '<S67>/Resettable Delay' */
|
||||
boolean_T UnitDelay1_DSTATE; /* '<S65>/UnitDelay1' */
|
||||
} DW_PI_clamp_fixdt_m;
|
||||
|
||||
/* Block signals and states (auto storage) for system '<S62>/PI_clamp_fixdt' */
|
||||
typedef struct {
|
||||
int16_T ResettableDelay_DSTATE; /* '<S72>/Resettable Delay' */
|
||||
uint8_T icLoad; /* '<S72>/Resettable Delay' */
|
||||
boolean_T UnitDelay1_DSTATE; /* '<S69>/UnitDelay1' */
|
||||
} DW_PI_clamp_fixdt_g;
|
||||
|
||||
/* Block signals and states (auto storage) for system '<Root>' */
|
||||
typedef struct {
|
||||
DW_PI_clamp_fixdt_g PI_clamp_fixdt_kh;/* '<S62>/PI_clamp_fixdt' */
|
||||
DW_PI_clamp_fixdt_m PI_clamp_fixdt_l4;/* '<S61>/PI_clamp_fixdt' */
|
||||
DW_PI_clamp_fixdt PI_clamp_fixdt_i; /* '<S63>/PI_clamp_fixdt' */
|
||||
DW_I_backCalc_fixdt I_backCalc_fixdt_j;/* '<S82>/I_backCalc_fixdt' */
|
||||
DW_I_backCalc_fixdt I_backCalc_fixdt1;/* '<S83>/I_backCalc_fixdt1' */
|
||||
DW_I_backCalc_fixdt I_backCalc_fixdt_i;/* '<S83>/I_backCalc_fixdt' */
|
||||
DW_either_edge either_edge_i; /* '<S20>/either_edge' */
|
||||
DW_Debounce_Filter Debounce_Filter_k;/* '<S20>/Debounce_Filter' */
|
||||
DW_Low_Pass_Filter Low_Pass_Filter_m;/* '<S50>/Low_Pass_Filter' */
|
||||
DW_Counter Counter_e; /* '<S13>/Counter' */
|
||||
int32_T Divide1; /* '<S81>/Divide1' */
|
||||
int32_T UnitDelay_DSTATE; /* '<S40>/UnitDelay' */
|
||||
int16_T Gain4_e[3]; /* '<S57>/Gain4' */
|
||||
int16_T DataTypeConversion[2]; /* '<S56>/Data Type Conversion' */
|
||||
int16_T z_counterRawPrev; /* '<S17>/z_counterRawPrev' */
|
||||
int16_T Merge; /* '<S59>/Merge' */
|
||||
int16_T Switch1; /* '<S78>/Switch1' */
|
||||
int16_T Vd_max1; /* '<S80>/Vd_max1' */
|
||||
int16_T Gain3; /* '<S80>/Gain3' */
|
||||
int16_T Vq_max_M1; /* '<S80>/Vq_max_M1' */
|
||||
int16_T Gain5; /* '<S80>/Gain5' */
|
||||
int16_T i_max; /* '<S80>/i_max' */
|
||||
int16_T Divide1_n; /* '<S80>/Divide1' */
|
||||
int16_T Gain1; /* '<S80>/Gain1' */
|
||||
int16_T Gain4; /* '<S80>/Gain4' */
|
||||
int16_T Switch2_i; /* '<S87>/Switch2' */
|
||||
int16_T Switch2_o; /* '<S93>/Switch2' */
|
||||
int16_T Switch2_a; /* '<S91>/Switch2' */
|
||||
int16_T Divide3; /* '<S42>/Divide3' */
|
||||
int16_T Merge1; /* '<S33>/Merge1' */
|
||||
int16_T Abs1; /* '<S5>/Abs1' */
|
||||
int16_T Abs5_h; /* '<S50>/Abs5' */
|
||||
int16_T Divide11; /* '<S17>/Divide11' */
|
||||
int16_T r_sin_M1; /* '<S52>/r_sin_M1' */
|
||||
int16_T r_cos_M1; /* '<S52>/r_cos_M1' */
|
||||
int16_T UnitDelay3_DSTATE; /* '<S13>/UnitDelay3' */
|
||||
int16_T UnitDelay4_DSTATE; /* '<S17>/UnitDelay4' */
|
||||
int16_T UnitDelay2_DSTATE; /* '<S17>/UnitDelay2' */
|
||||
int16_T UnitDelay3_DSTATE_o; /* '<S17>/UnitDelay3' */
|
||||
int16_T UnitDelay5_DSTATE; /* '<S17>/UnitDelay5' */
|
||||
int16_T UnitDelay4_DSTATE_e; /* '<S13>/UnitDelay4' */
|
||||
int16_T UnitDelay4_DSTATE_eu; /* '<S8>/UnitDelay4' */
|
||||
int8_T Switch2_e; /* '<S12>/Switch2' */
|
||||
int8_T UnitDelay2_DSTATE_b; /* '<S12>/UnitDelay2' */
|
||||
int8_T If1_ActiveSubsystem; /* '<S7>/If1' */
|
||||
int8_T If2_ActiveSubsystem; /* '<S7>/If2' */
|
||||
int8_T If1_ActiveSubsystem_j; /* '<S47>/If1' */
|
||||
int8_T SwitchCase_ActiveSubsystem; /* '<S59>/Switch Case' */
|
||||
int8_T If1_ActiveSubsystem_a; /* '<S59>/If1' */
|
||||
int8_T If1_ActiveSubsystem_o; /* '<S48>/If1' */
|
||||
int8_T SwitchCase_ActiveSubsystem_d; /* '<S80>/Switch Case' */
|
||||
int8_T If2_ActiveSubsystem_f; /* '<S33>/If2' */
|
||||
int8_T If2_ActiveSubsystem_a; /* '<S45>/If2' */
|
||||
uint8_T z_ctrlMod; /* '<S5>/F03_02_Control_Mode_Manager' */
|
||||
uint8_T UnitDelay3_DSTATE_fy; /* '<S10>/UnitDelay3' */
|
||||
uint8_T UnitDelay1_DSTATE; /* '<S10>/UnitDelay1' */
|
||||
uint8_T UnitDelay2_DSTATE_f; /* '<S10>/UnitDelay2' */
|
||||
uint8_T UnitDelay_DSTATE_e; /* '<S20>/UnitDelay' */
|
||||
uint8_T is_active_c1_BLDC_controller;/* '<S5>/F03_02_Control_Mode_Manager' */
|
||||
uint8_T is_c1_BLDC_controller; /* '<S5>/F03_02_Control_Mode_Manager' */
|
||||
uint8_T is_ACTIVE; /* '<S5>/F03_02_Control_Mode_Manager' */
|
||||
boolean_T Merge_p; /* '<S21>/Merge' */
|
||||
boolean_T dz_cntTrnsDet; /* '<S17>/dz_cntTrnsDet' */
|
||||
boolean_T UnitDelay2_DSTATE_c; /* '<S2>/UnitDelay2' */
|
||||
boolean_T UnitDelay5_DSTATE_m; /* '<S2>/UnitDelay5' */
|
||||
boolean_T UnitDelay6_DSTATE; /* '<S2>/UnitDelay6' */
|
||||
boolean_T UnitDelay_DSTATE_b; /* '<S39>/UnitDelay' */
|
||||
boolean_T UnitDelay1_DSTATE_n; /* '<S17>/UnitDelay1' */
|
||||
boolean_T n_commDeacv_Mode; /* '<S13>/n_commDeacv' */
|
||||
boolean_T dz_cntTrnsDet_Mode; /* '<S17>/dz_cntTrnsDet' */
|
||||
} DW;
|
||||
|
||||
/* Constant parameters (auto storage) */
|
||||
typedef struct {
|
||||
/* Computed Parameter: r_sin_M1_Table
|
||||
* Referenced by: '<S52>/r_sin_M1'
|
||||
*/
|
||||
int16_T r_sin_M1_Table[181];
|
||||
|
||||
/* Computed Parameter: r_cos_M1_Table
|
||||
* Referenced by: '<S52>/r_cos_M1'
|
||||
*/
|
||||
int16_T r_cos_M1_Table[181];
|
||||
|
||||
/* Computed Parameter: r_sin3PhaA_M1_Table
|
||||
* Referenced by: '<S96>/r_sin3PhaA_M1'
|
||||
*/
|
||||
int16_T r_sin3PhaA_M1_Table[181];
|
||||
|
||||
/* Computed Parameter: r_sin3PhaB_M1_Table
|
||||
* Referenced by: '<S96>/r_sin3PhaB_M1'
|
||||
*/
|
||||
int16_T r_sin3PhaB_M1_Table[181];
|
||||
|
||||
/* Computed Parameter: r_sin3PhaC_M1_Table
|
||||
* Referenced by: '<S96>/r_sin3PhaC_M1'
|
||||
*/
|
||||
int16_T r_sin3PhaC_M1_Table[181];
|
||||
|
||||
/* Computed Parameter: iq_maxSca_M1_Table
|
||||
* Referenced by: '<S80>/iq_maxSca_M1'
|
||||
*/
|
||||
uint16_T iq_maxSca_M1_Table[50];
|
||||
|
||||
/* Computed Parameter: z_commutMap_M1_table
|
||||
* Referenced by: '<S94>/z_commutMap_M1'
|
||||
*/
|
||||
int8_T z_commutMap_M1_table[18];
|
||||
|
||||
/* Computed Parameter: vec_hallToPos_Value
|
||||
* Referenced by: '<S11>/vec_hallToPos'
|
||||
*/
|
||||
int8_T vec_hallToPos_Value[8];
|
||||
} ConstP;
|
||||
|
||||
/* External inputs (root inport signals with auto storage) */
|
||||
typedef struct {
|
||||
boolean_T b_motEna; /* '<Root>/b_motEna' */
|
||||
uint8_T z_ctrlModReq; /* '<Root>/z_ctrlModReq' */
|
||||
int16_T r_inpTgt; /* '<Root>/r_inpTgt' */
|
||||
uint8_T b_hallA; /* '<Root>/b_hallA ' */
|
||||
uint8_T b_hallB; /* '<Root>/b_hallB' */
|
||||
uint8_T b_hallC; /* '<Root>/b_hallC' */
|
||||
int16_T i_phaAB; /* '<Root>/i_phaAB' */
|
||||
int16_T i_phaBC; /* '<Root>/i_phaBC' */
|
||||
int16_T i_DCLink; /* '<Root>/i_DCLink' */
|
||||
int16_T a_mechAngle; /* '<Root>/a_mechAngle' */
|
||||
} ExtU;
|
||||
|
||||
/* External outputs (root outports fed by signals with auto storage) */
|
||||
typedef struct {
|
||||
int16_T DC_phaA; /* '<Root>/DC_phaA' */
|
||||
int16_T DC_phaB; /* '<Root>/DC_phaB' */
|
||||
int16_T DC_phaC; /* '<Root>/DC_phaC' */
|
||||
uint8_T z_errCode; /* '<Root>/z_errCode' */
|
||||
int16_T n_mot; /* '<Root>/n_mot' */
|
||||
int16_T a_elecAngle; /* '<Root>/a_elecAngle' */
|
||||
int16_T iq; /* '<Root>/iq' */
|
||||
int16_T id; /* '<Root>/id' */
|
||||
} ExtY;
|
||||
|
||||
/* Parameters (auto storage) */
|
||||
struct P_ {
|
||||
int32_T dV_openRate; /* Variable: dV_openRate
|
||||
* Referenced by: '<S37>/dV_openRate'
|
||||
*/
|
||||
int16_T dz_cntTrnsDetHi; /* Variable: dz_cntTrnsDetHi
|
||||
* Referenced by: '<S17>/dz_cntTrnsDet'
|
||||
*/
|
||||
int16_T dz_cntTrnsDetLo; /* Variable: dz_cntTrnsDetLo
|
||||
* Referenced by: '<S17>/dz_cntTrnsDet'
|
||||
*/
|
||||
int16_T n_cruiseMotTgt; /* Variable: n_cruiseMotTgt
|
||||
* Referenced by: '<S61>/n_cruiseMotTgt'
|
||||
*/
|
||||
int16_T z_maxCntRst; /* Variable: z_maxCntRst
|
||||
* Referenced by:
|
||||
* '<S13>/Counter'
|
||||
* '<S13>/z_maxCntRst'
|
||||
* '<S13>/z_maxCntRst2'
|
||||
* '<S13>/UnitDelay3'
|
||||
* '<S17>/z_counter'
|
||||
*/
|
||||
uint16_T cf_speedCoef; /* Variable: cf_speedCoef
|
||||
* Referenced by: '<S17>/cf_speedCoef'
|
||||
*/
|
||||
uint16_T t_errDequal; /* Variable: t_errDequal
|
||||
* Referenced by: '<S20>/t_errDequal'
|
||||
*/
|
||||
uint16_T t_errQual; /* Variable: t_errQual
|
||||
* Referenced by: '<S20>/t_errQual'
|
||||
*/
|
||||
int16_T Vd_max; /* Variable: Vd_max
|
||||
* Referenced by:
|
||||
* '<S36>/Vd_max'
|
||||
* '<S80>/Vd_max1'
|
||||
*/
|
||||
int16_T Vq_max_M1[46]; /* Variable: Vq_max_M1
|
||||
* Referenced by: '<S80>/Vq_max_M1'
|
||||
*/
|
||||
int16_T Vq_max_XA[46]; /* Variable: Vq_max_XA
|
||||
* Referenced by: '<S80>/Vq_max_XA'
|
||||
*/
|
||||
int16_T a_phaAdvMax; /* Variable: a_phaAdvMax
|
||||
* Referenced by: '<S42>/a_phaAdvMax'
|
||||
*/
|
||||
int16_T i_max; /* Variable: i_max
|
||||
* Referenced by:
|
||||
* '<S36>/i_max'
|
||||
* '<S80>/i_max'
|
||||
*/
|
||||
int16_T id_fieldWeakMax; /* Variable: id_fieldWeakMax
|
||||
* Referenced by: '<S42>/id_fieldWeakMax'
|
||||
*/
|
||||
int16_T n_commAcvLo; /* Variable: n_commAcvLo
|
||||
* Referenced by: '<S13>/n_commDeacv'
|
||||
*/
|
||||
int16_T n_commDeacvHi; /* Variable: n_commDeacvHi
|
||||
* Referenced by: '<S13>/n_commDeacv'
|
||||
*/
|
||||
int16_T n_fieldWeakAuthHi; /* Variable: n_fieldWeakAuthHi
|
||||
* Referenced by: '<S42>/n_fieldWeakAuthHi'
|
||||
*/
|
||||
int16_T n_fieldWeakAuthLo; /* Variable: n_fieldWeakAuthLo
|
||||
* Referenced by: '<S42>/n_fieldWeakAuthLo'
|
||||
*/
|
||||
int16_T n_max; /* Variable: n_max
|
||||
* Referenced by:
|
||||
* '<S36>/n_max'
|
||||
* '<S80>/n_max1'
|
||||
*/
|
||||
int16_T n_stdStillDet; /* Variable: n_stdStillDet
|
||||
* Referenced by: '<S13>/n_stdStillDet'
|
||||
*/
|
||||
int16_T r_errInpTgtThres; /* Variable: r_errInpTgtThres
|
||||
* Referenced by: '<S20>/r_errInpTgtThres'
|
||||
*/
|
||||
int16_T r_fieldWeakHi; /* Variable: r_fieldWeakHi
|
||||
* Referenced by: '<S42>/r_fieldWeakHi'
|
||||
*/
|
||||
int16_T r_fieldWeakLo; /* Variable: r_fieldWeakLo
|
||||
* Referenced by: '<S42>/r_fieldWeakLo'
|
||||
*/
|
||||
uint16_T cf_KbLimProt; /* Variable: cf_KbLimProt
|
||||
* Referenced by:
|
||||
* '<S82>/cf_KbLimProt'
|
||||
* '<S83>/cf_KbLimProt'
|
||||
*/
|
||||
uint16_T cf_idKp; /* Variable: cf_idKp
|
||||
* Referenced by: '<S63>/cf_idKp1'
|
||||
*/
|
||||
uint16_T cf_iqKp; /* Variable: cf_iqKp
|
||||
* Referenced by: '<S62>/cf_iqKp'
|
||||
*/
|
||||
uint16_T cf_nKp; /* Variable: cf_nKp
|
||||
* Referenced by: '<S61>/cf_nKp'
|
||||
*/
|
||||
uint16_T cf_currFilt; /* Variable: cf_currFilt
|
||||
* Referenced by: '<S50>/cf_currFilt'
|
||||
*/
|
||||
uint16_T cf_idKi; /* Variable: cf_idKi
|
||||
* Referenced by: '<S63>/cf_idKi1'
|
||||
*/
|
||||
uint16_T cf_iqKi; /* Variable: cf_iqKi
|
||||
* Referenced by: '<S62>/cf_iqKi'
|
||||
*/
|
||||
uint16_T cf_iqKiLimProt; /* Variable: cf_iqKiLimProt
|
||||
* Referenced by:
|
||||
* '<S81>/cf_iqKiLimProt'
|
||||
* '<S83>/cf_iqKiLimProt'
|
||||
*/
|
||||
uint16_T cf_nKi; /* Variable: cf_nKi
|
||||
* Referenced by: '<S61>/cf_nKi'
|
||||
*/
|
||||
uint16_T cf_nKiLimProt; /* Variable: cf_nKiLimProt
|
||||
* Referenced by:
|
||||
* '<S82>/cf_nKiLimProt'
|
||||
* '<S83>/cf_nKiLimProt'
|
||||
*/
|
||||
uint8_T n_polePairs; /* Variable: n_polePairs
|
||||
* Referenced by: '<S15>/n_polePairs'
|
||||
*/
|
||||
uint8_T z_ctrlTypSel; /* Variable: z_ctrlTypSel
|
||||
* Referenced by: '<S1>/z_ctrlTypSel'
|
||||
*/
|
||||
uint8_T z_selPhaCurMeasABC; /* Variable: z_selPhaCurMeasABC
|
||||
* Referenced by: '<S49>/z_selPhaCurMeasABC'
|
||||
*/
|
||||
boolean_T b_angleMeasEna; /* Variable: b_angleMeasEna
|
||||
* Referenced by:
|
||||
* '<S3>/b_angleMeasEna'
|
||||
* '<S13>/b_angleMeasEna'
|
||||
*/
|
||||
boolean_T b_cruiseCtrlEna; /* Variable: b_cruiseCtrlEna
|
||||
* Referenced by: '<S1>/b_cruiseCtrlEna'
|
||||
*/
|
||||
boolean_T b_diagEna; /* Variable: b_diagEna
|
||||
* Referenced by: '<S4>/b_diagEna'
|
||||
*/
|
||||
boolean_T b_fieldWeakEna; /* Variable: b_fieldWeakEna
|
||||
* Referenced by:
|
||||
* '<S6>/b_fieldWeakEna'
|
||||
* '<S97>/b_fieldWeakEna'
|
||||
*/
|
||||
};
|
||||
|
||||
/* Parameters (auto storage) */
|
||||
typedef struct P_ P;
|
||||
|
||||
/* Real-time Model Data Structure */
|
||||
struct tag_RTM {
|
||||
P *defaultParam;
|
||||
ExtU *inputs;
|
||||
ExtY *outputs;
|
||||
DW *dwork;
|
||||
};
|
||||
|
||||
/* Constant parameters (auto storage) */
|
||||
extern const ConstP rtConstP;
|
||||
|
||||
/* Model entry point functions */
|
||||
extern void BLDC_controller_initialize(RT_MODEL *const rtM);
|
||||
extern void BLDC_controller_step(RT_MODEL *const rtM);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,386 @@
|
||||
/*
|
||||
* File: BLDC_controller_data.c
|
||||
*
|
||||
* Code generated for Simulink model 'BLDC_controller'.
|
||||
*
|
||||
* Model version : 1.1297
|
||||
* Simulink Coder version : 8.13 (R2017b) 24-Jul-2017
|
||||
* C/C++ source code generated on : Sun Mar 6 11:02:11 2022
|
||||
*
|
||||
* Target selection: ert.tlc
|
||||
* Embedded hardware selection: ARM Compatible->ARM Cortex
|
||||
* Emulation hardware selection:
|
||||
* Differs from embedded hardware (MATLAB Host)
|
||||
* Code generation objectives:
|
||||
* 1. Execution efficiency
|
||||
* 2. RAM efficiency
|
||||
* Validation result: Not run
|
||||
*/
|
||||
|
||||
#include "BLDC_controller.h"
|
||||
|
||||
/* Constant parameters (auto storage) */
|
||||
const ConstP rtConstP = {
|
||||
/* Computed Parameter: r_sin_M1_Table
|
||||
* Referenced by: '<S52>/r_sin_M1'
|
||||
*/
|
||||
{ 8192, 8682, 9162, 9630, 10087, 10531, 10963, 11381, 11786, 12176, 12551,
|
||||
12911, 13255, 13583, 13894, 14189, 14466, 14726, 14968, 15191, 15396, 15582,
|
||||
15749, 15897, 16026, 16135, 16225, 16294, 16344, 16374, 16384, 16374, 16344,
|
||||
16294, 16225, 16135, 16026, 15897, 15749, 15582, 15396, 15191, 14968, 14726,
|
||||
14466, 14189, 13894, 13583, 13255, 12911, 12551, 12176, 11786, 11381, 10963,
|
||||
10531, 10087, 9630, 9162, 8682, 8192, 7692, 7182, 6664, 6138, 5604, 5063,
|
||||
4516, 3964, 3406, 2845, 2280, 1713, 1143, 572, 0, -572, -1143, -1713, -2280,
|
||||
-2845, -3406, -3964, -4516, -5063, -5604, -6138, -6664, -7182, -7692, -8192,
|
||||
-8682, -9162, -9630, -10087, -10531, -10963, -11381, -11786, -12176, -12551,
|
||||
-12911, -13255, -13583, -13894, -14189, -14466, -14726, -14968, -15191,
|
||||
-15396, -15582, -15749, -15897, -16026, -16135, -16225, -16294, -16344,
|
||||
-16374, -16384, -16374, -16344, -16294, -16225, -16135, -16026, -15897,
|
||||
-15749, -15582, -15396, -15191, -14968, -14726, -14466, -14189, -13894,
|
||||
-13583, -13255, -12911, -12551, -12176, -11786, -11381, -10963, -10531,
|
||||
-10087, -9630, -9162, -8682, -8192, -7692, -7182, -6664, -6138, -5604, -5063,
|
||||
-4516, -3964, -3406, -2845, -2280, -1713, -1143, -572, 0, 572, 1143, 1713,
|
||||
2280, 2845, 3406, 3964, 4516, 5063, 5604, 6138, 6664, 7182, 7692, 8192 },
|
||||
|
||||
/* Computed Parameter: r_cos_M1_Table
|
||||
* Referenced by: '<S52>/r_cos_M1'
|
||||
*/
|
||||
{ 14189, 13894, 13583, 13255, 12911, 12551, 12176, 11786, 11381, 10963, 10531,
|
||||
10087, 9630, 9162, 8682, 8192, 7692, 7182, 6664, 6138, 5604, 5063, 4516,
|
||||
3964, 3406, 2845, 2280, 1713, 1143, 572, 0, -572, -1143, -1713, -2280, -2845,
|
||||
-3406, -3964, -4516, -5063, -5604, -6138, -6664, -7182, -7692, -8192, -8682,
|
||||
-9162, -9630, -10087, -10531, -10963, -11381, -11786, -12176, -12551, -12911,
|
||||
-13255, -13583, -13894, -14189, -14466, -14726, -14968, -15191, -15396,
|
||||
-15582, -15749, -15897, -16026, -16135, -16225, -16294, -16344, -16374,
|
||||
-16384, -16374, -16344, -16294, -16225, -16135, -16026, -15897, -15749,
|
||||
-15582, -15396, -15191, -14968, -14726, -14466, -14189, -13894, -13583,
|
||||
-13255, -12911, -12551, -12176, -11786, -11381, -10963, -10531, -10087,
|
||||
-9630, -9162, -8682, -8192, -7692, -7182, -6664, -6138, -5604, -5063, -4516,
|
||||
-3964, -3406, -2845, -2280, -1713, -1143, -572, 0, 572, 1143, 1713, 2280,
|
||||
2845, 3406, 3964, 4516, 5063, 5604, 6138, 6664, 7182, 7692, 8192, 8682, 9162,
|
||||
9630, 10087, 10531, 10963, 11381, 11786, 12176, 12551, 12911, 13255, 13583,
|
||||
13894, 14189, 14466, 14726, 14968, 15191, 15396, 15582, 15749, 15897, 16026,
|
||||
16135, 16225, 16294, 16344, 16374, 16384, 16374, 16344, 16294, 16225, 16135,
|
||||
16026, 15897, 15749, 15582, 15396, 15191, 14968, 14726, 14466, 14189 },
|
||||
|
||||
/* Computed Parameter: r_sin3PhaA_M1_Table
|
||||
* Referenced by: '<S96>/r_sin3PhaA_M1'
|
||||
*/
|
||||
{ -13091, -13634, -14126, -14565, -14953, -15289, -15577, -15816, -16009,
|
||||
-16159, -16269, -16340, -16377, -16383, -16362, -16317, -16253, -16172,
|
||||
-16079, -15977, -15870, -15762, -15656, -15555, -15461, -15377, -15306,
|
||||
-15248, -15206, -15180, -15172, -15180, -15206, -15248, -15306, -15377,
|
||||
-15461, -15555, -15656, -15762, -15870, -15977, -16079, -16172, -16253,
|
||||
-16317, -16362, -16383, -16377, -16340, -16269, -16159, -16009, -15816,
|
||||
-15577, -15289, -14953, -14565, -14126, -13634, -13091, -12496, -11849,
|
||||
-11154, -10411, -9623, -8791, -7921, -7014, -6075, -5107, -4115, -3104,
|
||||
-2077, -1041, 0, 1041, 2077, 3104, 4115, 5107, 6075, 7014, 7921, 8791, 9623,
|
||||
10411, 11154, 11849, 12496, 13091, 13634, 14126, 14565, 14953, 15289, 15577,
|
||||
15816, 16009, 16159, 16269, 16340, 16377, 16383, 16362, 16317, 16253, 16172,
|
||||
16079, 15977, 15870, 15762, 15656, 15555, 15461, 15377, 15306, 15248, 15206,
|
||||
15180, 15172, 15180, 15206, 15248, 15306, 15377, 15461, 15555, 15656, 15762,
|
||||
15870, 15977, 16079, 16172, 16253, 16317, 16362, 16383, 16377, 16340, 16269,
|
||||
16159, 16009, 15816, 15577, 15289, 14953, 14565, 14126, 13634, 13091, 12496,
|
||||
11849, 11154, 10411, 9623, 8791, 7921, 7014, 6075, 5107, 4115, 3104, 2077,
|
||||
1041, 0, -1041, -2077, -3104, -4115, -5107, -6075, -7014, -7921, -8791,
|
||||
-9623, -10411, -11154, -11849, -12496, -13091 },
|
||||
|
||||
/* Computed Parameter: r_sin3PhaB_M1_Table
|
||||
* Referenced by: '<S96>/r_sin3PhaB_M1'
|
||||
*/
|
||||
{ 15172, 15180, 15206, 15248, 15306, 15377, 15461, 15555, 15656, 15762, 15870,
|
||||
15977, 16079, 16172, 16253, 16317, 16362, 16383, 16377, 16340, 16269, 16159,
|
||||
16009, 15816, 15577, 15289, 14953, 14565, 14126, 13634, 13091, 12496, 11849,
|
||||
11154, 10411, 9623, 8791, 7921, 7014, 6075, 5107, 4115, 3104, 2077, 1041, 0,
|
||||
-1041, -2077, -3104, -4115, -5107, -6075, -7014, -7921, -8791, -9623, -10411,
|
||||
-11154, -11849, -12496, -13091, -13634, -14126, -14565, -14953, -15289,
|
||||
-15577, -15816, -16009, -16159, -16269, -16340, -16377, -16383, -16362,
|
||||
-16317, -16253, -16172, -16079, -15977, -15870, -15762, -15656, -15555,
|
||||
-15461, -15377, -15306, -15248, -15206, -15180, -15172, -15180, -15206,
|
||||
-15248, -15306, -15377, -15461, -15555, -15656, -15762, -15870, -15977,
|
||||
-16079, -16172, -16253, -16317, -16362, -16383, -16377, -16340, -16269,
|
||||
-16159, -16009, -15816, -15577, -15289, -14953, -14565, -14126, -13634,
|
||||
-13091, -12496, -11849, -11154, -10411, -9623, -8791, -7921, -7014, -6075,
|
||||
-5107, -4115, -3104, -2077, -1041, 0, 1041, 2077, 3104, 4115, 5107, 6075,
|
||||
7014, 7921, 8791, 9623, 10411, 11154, 11849, 12496, 13091, 13634, 14126,
|
||||
14565, 14953, 15289, 15577, 15816, 16009, 16159, 16269, 16340, 16377, 16383,
|
||||
16362, 16317, 16253, 16172, 16079, 15977, 15870, 15762, 15656, 15555, 15461,
|
||||
15377, 15306, 15248, 15206, 15180, 15172 },
|
||||
|
||||
/* Computed Parameter: r_sin3PhaC_M1_Table
|
||||
* Referenced by: '<S96>/r_sin3PhaC_M1'
|
||||
*/
|
||||
{ -13091, -12496, -11849, -11154, -10411, -9623, -8791, -7921, -7014, -6075,
|
||||
-5107, -4115, -3104, -2077, -1041, 0, 1041, 2077, 3104, 4115, 5107, 6075,
|
||||
7014, 7921, 8791, 9623, 10411, 11154, 11849, 12496, 13091, 13634, 14126,
|
||||
14565, 14953, 15289, 15577, 15816, 16009, 16159, 16269, 16340, 16377, 16383,
|
||||
16362, 16317, 16253, 16172, 16079, 15977, 15870, 15762, 15656, 15555, 15461,
|
||||
15377, 15306, 15248, 15206, 15180, 15172, 15180, 15206, 15248, 15306, 15377,
|
||||
15461, 15555, 15656, 15762, 15870, 15977, 16079, 16172, 16253, 16317, 16362,
|
||||
16383, 16377, 16340, 16269, 16159, 16009, 15816, 15577, 15289, 14953, 14565,
|
||||
14126, 13634, 13091, 12496, 11849, 11154, 10411, 9623, 8791, 7921, 7014,
|
||||
6075, 5107, 4115, 3104, 2077, 1041, 0, -1041, -2077, -3104, -4115, -5107,
|
||||
-6075, -7014, -7921, -8791, -9623, -10411, -11154, -11849, -12496, -13091,
|
||||
-13634, -14126, -14565, -14953, -15289, -15577, -15816, -16009, -16159,
|
||||
-16269, -16340, -16377, -16383, -16362, -16317, -16253, -16172, -16079,
|
||||
-15977, -15870, -15762, -15656, -15555, -15461, -15377, -15306, -15248,
|
||||
-15206, -15180, -15172, -15180, -15206, -15248, -15306, -15377, -15461,
|
||||
-15555, -15656, -15762, -15870, -15977, -16079, -16172, -16253, -16317,
|
||||
-16362, -16383, -16377, -16340, -16269, -16159, -16009, -15816, -15577,
|
||||
-15289, -14953, -14565, -14126, -13634, -13091 },
|
||||
|
||||
/* Computed Parameter: iq_maxSca_M1_Table
|
||||
* Referenced by: '<S80>/iq_maxSca_M1'
|
||||
*/
|
||||
{ 65535U, 65523U, 65484U, 65418U, 65326U, 65207U, 65062U, 64890U, 64691U,
|
||||
64465U, 64211U, 63930U, 63620U, 63281U, 62913U, 62516U, 62088U, 61630U,
|
||||
61140U, 60618U, 60062U, 59473U, 58848U, 58187U, 57489U, 56752U, 55974U,
|
||||
55155U, 54291U, 53381U, 52422U, 51413U, 50349U, 49227U, 48043U, 46792U,
|
||||
45470U, 44069U, 42581U, 40997U, 39307U, 37494U, 35541U, 33422U, 31105U,
|
||||
28540U, 25655U, 22323U, 18304U, 12974U },
|
||||
|
||||
/* Computed Parameter: z_commutMap_M1_table
|
||||
* Referenced by: '<S94>/z_commutMap_M1'
|
||||
*/
|
||||
{ -1, 1, 0, -1, 0, 1, 0, -1, 1, 1, -1, 0, 1, 0, -1, 0, 1, -1 },
|
||||
|
||||
/* Computed Parameter: vec_hallToPos_Value
|
||||
* Referenced by: '<S11>/vec_hallToPos'
|
||||
*/
|
||||
{ 0, 2, 0, 1, 4, 3, 5, 0 }
|
||||
};
|
||||
|
||||
P rtP_Left = {
|
||||
/* Variable: dV_openRate
|
||||
* Referenced by: '<S37>/dV_openRate'
|
||||
*/
|
||||
12288,
|
||||
|
||||
/* Variable: dz_cntTrnsDetHi
|
||||
* Referenced by: '<S17>/dz_cntTrnsDet'
|
||||
*/
|
||||
40,
|
||||
|
||||
/* Variable: dz_cntTrnsDetLo
|
||||
* Referenced by: '<S17>/dz_cntTrnsDet'
|
||||
*/
|
||||
20,
|
||||
|
||||
/* Variable: n_cruiseMotTgt
|
||||
* Referenced by: '<S61>/n_cruiseMotTgt'
|
||||
*/
|
||||
0,
|
||||
|
||||
/* Variable: z_maxCntRst
|
||||
* Referenced by:
|
||||
* '<S13>/Counter'
|
||||
* '<S13>/z_maxCntRst'
|
||||
* '<S13>/z_maxCntRst2'
|
||||
* '<S13>/UnitDelay3'
|
||||
* '<S17>/z_counter'
|
||||
*/
|
||||
2000,
|
||||
|
||||
/* Variable: cf_speedCoef
|
||||
* Referenced by: '<S17>/cf_speedCoef'
|
||||
*/
|
||||
5334U,
|
||||
|
||||
/* Variable: t_errDequal
|
||||
* Referenced by: '<S20>/t_errDequal'
|
||||
*/
|
||||
9600U,
|
||||
|
||||
/* Variable: t_errQual
|
||||
* Referenced by: '<S20>/t_errQual'
|
||||
*/
|
||||
1280U,
|
||||
|
||||
/* Variable: Vd_max
|
||||
* Referenced by:
|
||||
* '<S36>/Vd_max'
|
||||
* '<S80>/Vd_max1'
|
||||
*/
|
||||
14400,
|
||||
|
||||
/* Variable: Vq_max_M1
|
||||
* Referenced by: '<S80>/Vq_max_M1'
|
||||
*/
|
||||
{ 14400, 14396, 14386, 14368, 14343, 14311, 14271, 14225, 14171, 14109, 14040,
|
||||
13963, 13879, 13786, 13685, 13576, 13459, 13333, 13198, 13053, 12900, 12736,
|
||||
12562, 12377, 12181, 11973, 11753, 11520, 11273, 11011, 10733, 10438, 10124,
|
||||
9790, 9433, 9051, 8640, 8196, 7713, 7184, 6597, 5935, 5170, 4245, 3019, 0 },
|
||||
|
||||
/* Variable: Vq_max_XA
|
||||
* Referenced by: '<S80>/Vq_max_XA'
|
||||
*/
|
||||
{ 0, 320, 640, 960, 1280, 1600, 1920, 2240, 2560, 2880, 3200, 3520, 3840, 4160,
|
||||
4480, 4800, 5120, 5440, 5760, 6080, 6400, 6720, 7040, 7360, 7680, 8000, 8320,
|
||||
8640, 8960, 9280, 9600, 9920, 10240, 10560, 10880, 11200, 11520, 11840,
|
||||
12160, 12480, 12800, 13120, 13440, 13760, 14080, 14400 },
|
||||
|
||||
/* Variable: a_phaAdvMax
|
||||
* Referenced by: '<S42>/a_phaAdvMax'
|
||||
*/
|
||||
400,
|
||||
|
||||
/* Variable: i_max
|
||||
* Referenced by:
|
||||
* '<S36>/i_max'
|
||||
* '<S80>/i_max'
|
||||
*/
|
||||
30000,
|
||||
|
||||
/* Variable: id_fieldWeakMax
|
||||
* Referenced by: '<S42>/id_fieldWeakMax'
|
||||
*/
|
||||
4000,
|
||||
|
||||
/* Variable: n_commAcvLo
|
||||
* Referenced by: '<S13>/n_commDeacv'
|
||||
*/
|
||||
240,
|
||||
|
||||
/* Variable: n_commDeacvHi
|
||||
* Referenced by: '<S13>/n_commDeacv'
|
||||
*/
|
||||
480,
|
||||
|
||||
/* Variable: n_fieldWeakAuthHi
|
||||
* Referenced by: '<S42>/n_fieldWeakAuthHi'
|
||||
*/
|
||||
6400,
|
||||
|
||||
/* Variable: n_fieldWeakAuthLo
|
||||
* Referenced by: '<S42>/n_fieldWeakAuthLo'
|
||||
*/
|
||||
4800,
|
||||
|
||||
/* Variable: n_max
|
||||
* Referenced by:
|
||||
* '<S36>/n_max'
|
||||
* '<S80>/n_max1'
|
||||
*/
|
||||
32000,
|
||||
|
||||
/* Variable: n_stdStillDet
|
||||
* Referenced by: '<S13>/n_stdStillDet'
|
||||
*/
|
||||
48,
|
||||
|
||||
/* Variable: r_errInpTgtThres
|
||||
* Referenced by: '<S20>/r_errInpTgtThres'
|
||||
*/
|
||||
9600,
|
||||
|
||||
/* Variable: r_fieldWeakHi
|
||||
* Referenced by: '<S42>/r_fieldWeakHi'
|
||||
*/
|
||||
16000,
|
||||
|
||||
/* Variable: r_fieldWeakLo
|
||||
* Referenced by: '<S42>/r_fieldWeakLo'
|
||||
*/
|
||||
12000,
|
||||
|
||||
/* Variable: cf_KbLimProt
|
||||
* Referenced by:
|
||||
* '<S82>/cf_KbLimProt'
|
||||
* '<S83>/cf_KbLimProt'
|
||||
*/
|
||||
768U,
|
||||
|
||||
/* Variable: cf_idKp
|
||||
* Referenced by: '<S63>/cf_idKp1'
|
||||
*/
|
||||
1638U,
|
||||
|
||||
/* Variable: cf_iqKp
|
||||
* Referenced by: '<S62>/cf_iqKp'
|
||||
*/
|
||||
2458U,
|
||||
|
||||
/* Variable: cf_nKp
|
||||
* Referenced by: '<S61>/cf_nKp'
|
||||
*/
|
||||
9666U,
|
||||
|
||||
/* Variable: cf_currFilt
|
||||
* Referenced by: '<S50>/cf_currFilt'
|
||||
*/
|
||||
7864U,
|
||||
|
||||
/* Variable: cf_idKi
|
||||
* Referenced by: '<S63>/cf_idKi1'
|
||||
*/
|
||||
1474U,
|
||||
|
||||
/* Variable: cf_iqKi
|
||||
* Referenced by: '<S62>/cf_iqKi'
|
||||
*/
|
||||
2458U,
|
||||
|
||||
/* Variable: cf_iqKiLimProt
|
||||
* Referenced by:
|
||||
* '<S81>/cf_iqKiLimProt'
|
||||
* '<S83>/cf_iqKiLimProt'
|
||||
*/
|
||||
1474U,
|
||||
|
||||
/* Variable: cf_nKi
|
||||
* Referenced by: '<S61>/cf_nKi'
|
||||
*/
|
||||
502U,
|
||||
|
||||
/* Variable: cf_nKiLimProt
|
||||
* Referenced by:
|
||||
* '<S82>/cf_nKiLimProt'
|
||||
* '<S83>/cf_nKiLimProt'
|
||||
*/
|
||||
492U,
|
||||
|
||||
/* Variable: n_polePairs
|
||||
* Referenced by: '<S15>/n_polePairs'
|
||||
*/
|
||||
15U,
|
||||
|
||||
/* Variable: z_ctrlTypSel
|
||||
* Referenced by: '<S1>/z_ctrlTypSel'
|
||||
*/
|
||||
2U,
|
||||
|
||||
/* Variable: z_selPhaCurMeasABC
|
||||
* Referenced by: '<S49>/z_selPhaCurMeasABC'
|
||||
*/
|
||||
0U,
|
||||
|
||||
/* Variable: b_angleMeasEna
|
||||
* Referenced by:
|
||||
* '<S3>/b_angleMeasEna'
|
||||
* '<S13>/b_angleMeasEna'
|
||||
*/
|
||||
0,
|
||||
|
||||
/* Variable: b_cruiseCtrlEna
|
||||
* Referenced by: '<S1>/b_cruiseCtrlEna'
|
||||
*/
|
||||
0,
|
||||
|
||||
/* Variable: b_diagEna
|
||||
* Referenced by: '<S4>/b_diagEna'
|
||||
*/
|
||||
1,
|
||||
|
||||
/* Variable: b_fieldWeakEna
|
||||
* Referenced by:
|
||||
* '<S6>/b_fieldWeakEna'
|
||||
* '<S97>/b_fieldWeakEna'
|
||||
*/
|
||||
0
|
||||
}; /* Modifiable parameters */
|
||||
|
||||
/*
|
||||
* File trailer for generated code.
|
||||
*
|
||||
* [EOF]
|
||||
*/
|
||||
@@ -0,0 +1,311 @@
|
||||
#ifndef BLDC_H
|
||||
#define BLDC_H
|
||||
|
||||
#include "board/body/bldc/bldc_defs.h"
|
||||
#include "board/body/boards/board_declarations.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "board/stm32h7/lladc.h"
|
||||
|
||||
// Matlab includes and defines - from auto-code generation
|
||||
#include "BLDC_controller.h" /* Model's header file */
|
||||
#include "BLDC_controller.c"
|
||||
#include "BLDC_controller_data.c"
|
||||
#include "rtwtypes.h"
|
||||
|
||||
static RT_MODEL rtM_Left_Obj;
|
||||
static RT_MODEL rtM_Right_Obj;
|
||||
|
||||
RT_MODEL *const rtM_Left = &rtM_Left_Obj;
|
||||
RT_MODEL *const rtM_Right = &rtM_Right_Obj;
|
||||
|
||||
static DW rtDW_Left; /* Observable states */
|
||||
static ExtU rtU_Left; /* External inputs */
|
||||
static ExtY rtY_Left; /* External outputs */
|
||||
extern P rtP_Left; // This is defined in BLDC_controller_data.c
|
||||
|
||||
static DW rtDW_Right; /* Observable states */
|
||||
static ExtU rtU_Right; /* External inputs */
|
||||
static ExtY rtY_Right; /* External outputs */
|
||||
static P rtP_Right; /* Parameters */
|
||||
|
||||
//static int16_t curDC_max = (I_DC_MAX * A2BIT_CONV);
|
||||
static int16_t curL_phaA = 0, curL_phaC = 0, curL_DC = 0;
|
||||
static int16_t curR_phaA = 0, curR_phaC = 0, curR_DC = 0;
|
||||
|
||||
volatile uint16_t batt_voltage_raw = 0;
|
||||
volatile uint16_t batt_percentage = 0;
|
||||
|
||||
volatile int rpm_left = 0;
|
||||
volatile int rpm_right = 0;
|
||||
|
||||
volatile bool enable_motors = 0; // initially motors are disabled for safety
|
||||
static bool enableFin = 0;
|
||||
|
||||
static const uint16_t pwm_res = ( (uint32_t)CORE_FREQ * 1000000U / 2U ) / PWM_FREQ;
|
||||
|
||||
static uint16_t offsetcount = 0;
|
||||
static uint32_t offsetrlA = 0;
|
||||
static uint32_t offsetrlC = 0;
|
||||
static uint32_t offsetrrA = 0;
|
||||
static uint32_t offsetrrC = 0;
|
||||
static uint32_t offsetdcl = 0;
|
||||
static uint32_t offsetdcr = 0;
|
||||
|
||||
#define ADC_CHANNEL_BLDC(a, c) {.adc = (a), .channel = (c), .sample_time = SAMPLETIME_16_CYCLES, .oversampling = OVERSAMPLING_4}
|
||||
|
||||
const adc_signal_t adc_curL_phaA = ADC_CHANNEL_BLDC(ADC2, 10);
|
||||
const adc_signal_t adc_curL_phaC = ADC_CHANNEL_BLDC(ADC2, 11);
|
||||
const adc_signal_t adc_curL_DC = ADC_CHANNEL_BLDC(ADC2, 18);
|
||||
const adc_signal_t adc_curR_phaA = ADC_CHANNEL_BLDC(ADC1, 7);
|
||||
const adc_signal_t adc_curR_phaC = ADC_CHANNEL_BLDC(ADC1, 15);
|
||||
const adc_signal_t adc_curR_DC = ADC_CHANNEL_BLDC(ADC1, 5);
|
||||
const adc_signal_t adc_batVoltage = ADC_CHANNEL_BLDC(ADC1, 4);
|
||||
|
||||
void motor_set_enable(bool enable) {
|
||||
enable_motors = enable;
|
||||
}
|
||||
|
||||
float motor_encoder_get_speed_rpm(uint8_t motor) {
|
||||
float speed_rpm = 0.0f;
|
||||
if (motor == BODY_MOTOR_LEFT) {
|
||||
speed_rpm = (float)rtY_Left.n_mot;
|
||||
} else if (motor == BODY_MOTOR_RIGHT) {
|
||||
speed_rpm = (float)rtY_Right.n_mot;
|
||||
}
|
||||
|
||||
if (ABS(speed_rpm) < RPM_DEADBAND) {
|
||||
speed_rpm = 0.0f;
|
||||
}
|
||||
|
||||
return speed_rpm;
|
||||
}
|
||||
|
||||
void bldc_init(void) {
|
||||
adc_init(ADC1);
|
||||
adc_init(ADC2);
|
||||
|
||||
// Initialize Hall Sensors for Left Motor (PB6, PB7, PB8)
|
||||
set_gpio_mode(GPIOB, 6, MODE_INPUT); set_gpio_pullup(GPIOB, 6, PULL_UP);
|
||||
set_gpio_mode(GPIOB, 7, MODE_INPUT); set_gpio_pullup(GPIOB, 7, PULL_UP);
|
||||
set_gpio_mode(GPIOB, 8, MODE_INPUT); set_gpio_pullup(GPIOB, 8, PULL_UP);
|
||||
|
||||
// Initialize Hall Sensors for Right Motor (PA0, PA1, PA2)
|
||||
set_gpio_mode(GPIOA, 0, MODE_INPUT); set_gpio_pullup(GPIOA, 0, PULL_UP);
|
||||
set_gpio_mode(GPIOA, 1, MODE_INPUT); set_gpio_pullup(GPIOA, 1, PULL_UP);
|
||||
set_gpio_mode(GPIOA, 2, MODE_INPUT); set_gpio_pullup(GPIOA, 2, PULL_UP);
|
||||
|
||||
// Setup the model pointers for Left motor
|
||||
rtM_Left->defaultParam = &rtP_Left;
|
||||
rtM_Left->inputs = &rtU_Left;
|
||||
rtM_Left->outputs = &rtY_Left;
|
||||
rtM_Left->dwork = &rtDW_Left;
|
||||
BLDC_controller_initialize(rtM_Left);
|
||||
|
||||
/* Set BLDC controller parameters */
|
||||
rtP_Left.b_angleMeasEna = 0; // Motor angle input: 0 = estimated angle, 1 = measured angle
|
||||
rtP_Left.z_selPhaCurMeasABC = 2; // Left motor measured current phases {Green, Blue} = {iA, iB}
|
||||
rtP_Left.z_ctrlTypSel = CTRL_TYP_SEL;
|
||||
rtP_Left.b_diagEna = DIAG_ENA;
|
||||
rtP_Left.i_max = (int16_t)(I_MOT_MAX * A2BIT_CONV) << 4;
|
||||
rtP_Left.n_max = N_MOT_MAX << 4;
|
||||
rtP_Left.b_fieldWeakEna = FIELD_WEAK_ENA;
|
||||
rtP_Left.id_fieldWeakMax = (int16_t)(FIELD_WEAK_MAX * A2BIT_CONV) << 4;
|
||||
rtP_Left.a_phaAdvMax = PHASE_ADV_MAX << 4;
|
||||
rtP_Left.r_fieldWeakHi = FIELD_WEAK_HI << 4;
|
||||
rtP_Left.r_fieldWeakLo = FIELD_WEAK_LO << 4;
|
||||
rtP_Left.z_maxCntRst = 4000;
|
||||
rtP_Left.cf_speedCoef = CF_SPEED_COEF;
|
||||
rtP_Left.t_errQual = 1280U; // 80ms at 16kHz loop rate
|
||||
rtP_Left.t_errDequal = T_ERR_DEQUAL_CYCLES;
|
||||
|
||||
// Setup the model pointers for Right motor
|
||||
rtP_Right = rtP_Left; // copy parameters
|
||||
// Right motor measured current phases A & C (based on adc_curR_phaA/C definitions)
|
||||
rtP_Right.z_selPhaCurMeasABC = 2;
|
||||
rtM_Right->defaultParam = &rtP_Right;
|
||||
rtM_Right->inputs = &rtU_Right;
|
||||
rtM_Right->outputs = &rtY_Right;
|
||||
rtM_Right->dwork = &rtDW_Right;
|
||||
BLDC_controller_initialize(rtM_Right);
|
||||
|
||||
// Initialize GPIOs for Motor Control
|
||||
// Left Motor (TIM1): PE8(CH1N), PE9(CH1), PE10(CH2N), PE11(CH2), PE12(CH3N), PE13(CH3)
|
||||
set_gpio_alternate(GPIOE, 8, GPIO_AF1_TIM1);
|
||||
set_gpio_alternate(GPIOE, 9, GPIO_AF1_TIM1);
|
||||
set_gpio_alternate(GPIOE, 10, GPIO_AF1_TIM1);
|
||||
set_gpio_alternate(GPIOE, 11, GPIO_AF1_TIM1);
|
||||
set_gpio_alternate(GPIOE, 12, GPIO_AF1_TIM1);
|
||||
set_gpio_alternate(GPIOE, 13, GPIO_AF1_TIM1);
|
||||
|
||||
// Right Motor (TIM8): PC6(CH1), PC7(CH2), PC8(CH3), PA5(CH1N), PB14(CH2N), PB15(CH3N)
|
||||
set_gpio_alternate(GPIOC, 6, GPIO_AF3_TIM8);
|
||||
set_gpio_alternate(GPIOC, 7, GPIO_AF3_TIM8);
|
||||
set_gpio_alternate(GPIOC, 8, GPIO_AF3_TIM8);
|
||||
set_gpio_alternate(GPIOA, 5, GPIO_AF3_TIM8);
|
||||
set_gpio_alternate(GPIOB, 14, GPIO_AF3_TIM8);
|
||||
set_gpio_alternate(GPIOB, 15, GPIO_AF3_TIM8);
|
||||
|
||||
// --- LEFT MOTOR (TIM1) ---
|
||||
// TIM8 is an advanced control timer. We configure it for 3-phase center-aligned PWM.
|
||||
LEFT_TIM->PSC = 0;
|
||||
LEFT_TIM->ARR = pwm_res; // Set auto-reload register for PWM_FREQ
|
||||
LEFT_TIM->CR1 = TIM_CR1_CMS_0; // Center-aligned mode 1
|
||||
LEFT_TIM->RCR = 1; // Update event once per 2 PWM periods (16kHz)
|
||||
|
||||
// Configure channel 1, 2, 3 as PWM mode 1, with preload enabled
|
||||
LEFT_TIM->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1PE | \
|
||||
TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2PE;
|
||||
LEFT_TIM->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3PE;
|
||||
|
||||
// Enable complementary outputs for channels 1, 2, 3
|
||||
LEFT_TIM->CCER = TIM_CCER_CC1E | TIM_CCER_CC1NE | \
|
||||
TIM_CCER_CC2E | TIM_CCER_CC2NE | \
|
||||
TIM_CCER_CC3E | TIM_CCER_CC3NE;
|
||||
|
||||
// --- RIGHT MOTOR (TIM8) ---
|
||||
RIGHT_TIM->PSC = 0;
|
||||
RIGHT_TIM->ARR = pwm_res;
|
||||
RIGHT_TIM->CR1 = TIM_CR1_CMS_0;
|
||||
RIGHT_TIM->RCR = 1;
|
||||
|
||||
RIGHT_TIM->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1PE | \
|
||||
TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2PE;
|
||||
RIGHT_TIM->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3PE;
|
||||
|
||||
RIGHT_TIM->CCER = TIM_CCER_CC1E | TIM_CCER_CC1NE | \
|
||||
TIM_CCER_CC2E | TIM_CCER_CC2NE | \
|
||||
TIM_CCER_CC3E | TIM_CCER_CC3NE;
|
||||
|
||||
// Set dead time (20 cycles -> ~166ns with 120MHz clock) and enable motor outputs
|
||||
LEFT_TIM->BDTR = 20U | TIM_BDTR_MOE;
|
||||
RIGHT_TIM->BDTR = 20U | TIM_BDTR_MOE;
|
||||
|
||||
// Generate an update event to load the registers
|
||||
LEFT_TIM->EGR = TIM_EGR_UG;
|
||||
RIGHT_TIM->EGR = TIM_EGR_UG;
|
||||
|
||||
// Enable TIM8 update interrupt for bldc_step
|
||||
LEFT_TIM->DIER |= TIM_DIER_UIE;
|
||||
|
||||
// Start the timers
|
||||
LEFT_TIM->CR1 |= TIM_CR1_CEN;
|
||||
RIGHT_TIM->CR1 |= TIM_CR1_CEN;
|
||||
}
|
||||
|
||||
void bldc_step(void) {
|
||||
// Calibrate ADC offsets for the first few cycles
|
||||
if(offsetcount < 2000) { // calibrate ADC offsets
|
||||
offsetcount++;
|
||||
uint32_t rawL_A = adc_get_raw(&adc_curL_phaA);
|
||||
uint32_t rawL_C = adc_get_raw(&adc_curL_phaC);
|
||||
uint32_t rawR_A = adc_get_raw(&adc_curR_phaA);
|
||||
uint32_t rawR_C = adc_get_raw(&adc_curR_phaC);
|
||||
uint32_t rawL_DC = adc_get_raw(&adc_curL_DC);
|
||||
uint32_t rawR_DC = adc_get_raw(&adc_curR_DC);
|
||||
|
||||
if (offsetcount == 1) {
|
||||
offsetrlA = rawL_A; offsetrlC = rawL_C;
|
||||
offsetrrA = rawR_A; offsetrrC = rawR_C;
|
||||
offsetdcl = rawL_DC; offsetdcr = rawR_DC;
|
||||
} else {
|
||||
offsetrlA = (rawL_A + offsetrlA) / 2;
|
||||
offsetrlC = (rawL_C + offsetrlC) / 2;
|
||||
offsetrrA = (rawR_A + offsetrrA) / 2;
|
||||
offsetrrC = (rawR_C + offsetrrC) / 2;
|
||||
offsetdcl = (rawL_DC + offsetdcl) / 2;
|
||||
offsetdcr = (rawR_DC + offsetdcr) / 2;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Get Left motor currents
|
||||
curL_phaA = (int16_t)(((int32_t)offsetrlA - (int32_t)adc_get_raw(&adc_curL_phaA)) >> 5);
|
||||
curL_phaC = (int16_t)(((int32_t)offsetrlC - (int32_t)adc_get_raw(&adc_curL_phaC)) >> 5);
|
||||
curL_DC = (int16_t)(((int32_t)offsetdcl - (int32_t)adc_get_raw(&adc_curL_DC)) >> 4);
|
||||
|
||||
// Get Right motor currents
|
||||
curR_phaA = (int16_t)(((int32_t)offsetrrA - (int32_t)adc_get_raw(&adc_curR_phaA)) >> 5);
|
||||
curR_phaC = (int16_t)(((int32_t)offsetrrC - (int32_t)adc_get_raw(&adc_curR_phaC)) >> 5);
|
||||
curR_DC = (int16_t)(((int32_t)offsetdcr - (int32_t)adc_get_raw(&adc_curR_DC)) >> 4);
|
||||
|
||||
// Safety: Don't enable if offsets are bogus (e.g. ADC failed)
|
||||
if (offsetrrA == 0 || offsetrrC == 0 || !enable_motors) {
|
||||
enableFin = 0;
|
||||
} else {
|
||||
enableFin = 1;
|
||||
}
|
||||
|
||||
// Read Hall Sensors
|
||||
rtU_Left.b_hallA = !((GPIOB->IDR >> 6) & 1);
|
||||
rtU_Left.b_hallB = !((GPIOB->IDR >> 7) & 1);
|
||||
rtU_Left.b_hallC = !((GPIOB->IDR >> 8) & 1);
|
||||
|
||||
rtU_Right.b_hallA = !((GPIOA->IDR >> 0) & 1);
|
||||
rtU_Right.b_hallB = !((GPIOA->IDR >> 1) & 1);
|
||||
rtU_Right.b_hallC = !((GPIOA->IDR >> 2) & 1);
|
||||
|
||||
if (!enableFin) {
|
||||
LEFT_TIM->BDTR &= ~TIM_BDTR_MOE;
|
||||
RIGHT_TIM->BDTR &= ~TIM_BDTR_MOE;
|
||||
} else {
|
||||
LEFT_TIM->BDTR |= TIM_BDTR_MOE;
|
||||
RIGHT_TIM->BDTR |= TIM_BDTR_MOE;
|
||||
}
|
||||
|
||||
// read battery voltage
|
||||
batt_voltage_raw = adc_get_raw(&adc_batVoltage);
|
||||
|
||||
int16_t batVoltageCalib = batt_voltage_raw * BAT_CALIB_REAL_VOLTAGE / BAT_CALIB_ADC;
|
||||
batt_percentage = 100 - (((420 * BAT_CELLS) - batVoltageCalib) / BAT_CELLS / VOLTS_PER_PERCENT / 100);
|
||||
|
||||
// ========================= LEFT MOTOR ===========================
|
||||
rtU_Left.b_motEna = enableFin;
|
||||
rtU_Left.z_ctrlModReq = CTRL_MOD_REQ; // Speed Mode
|
||||
int deadband_rpm_left = rpm_left;
|
||||
if (ABS(deadband_rpm_left) < RPM_DEADBAND) {
|
||||
deadband_rpm_left = 0;
|
||||
}
|
||||
rtU_Left.r_inpTgt = (CLAMP((int)deadband_rpm_left, -MAX_RPM, MAX_RPM) * RPM_TO_UNIT);
|
||||
|
||||
rtU_Left.i_phaAB = curL_phaA;
|
||||
rtU_Left.i_phaBC = curL_phaC;
|
||||
rtU_Left.i_DCLink = curL_DC;
|
||||
|
||||
BLDC_controller_step(rtM_Left);
|
||||
|
||||
int ul = rtY_Left.DC_phaA;
|
||||
int vl = rtY_Left.DC_phaB;
|
||||
int wl = rtY_Left.DC_phaC;
|
||||
|
||||
LEFT_TIM->CCR1 = (uint16_t)CLAMP((ul + pwm_res / 2), PWM_MARGIN, pwm_res - PWM_MARGIN);
|
||||
LEFT_TIM->CCR2 = (uint16_t)CLAMP((vl + pwm_res / 2), PWM_MARGIN, pwm_res - PWM_MARGIN);
|
||||
LEFT_TIM->CCR3 = (uint16_t)CLAMP((wl + pwm_res / 2), PWM_MARGIN, pwm_res - PWM_MARGIN);
|
||||
|
||||
// ========================= RIGHT MOTOR ===========================
|
||||
rtU_Right.b_motEna = enableFin;
|
||||
rtU_Right.z_ctrlModReq = CTRL_MOD_REQ; // Speed Mode
|
||||
int deadband_rpm_right = rpm_right;
|
||||
if (ABS(deadband_rpm_right) < RPM_DEADBAND) {
|
||||
deadband_rpm_right = 0;
|
||||
}
|
||||
rtU_Right.r_inpTgt = -(CLAMP((int)deadband_rpm_right, -MAX_RPM, MAX_RPM) * RPM_TO_UNIT);
|
||||
|
||||
rtU_Right.i_phaAB = curR_phaA;
|
||||
rtU_Right.i_phaBC = curR_phaC;
|
||||
rtU_Right.i_DCLink = curR_DC;
|
||||
|
||||
BLDC_controller_step(rtM_Right);
|
||||
|
||||
int ur = rtY_Right.DC_phaA;
|
||||
int vr = rtY_Right.DC_phaB;
|
||||
int wr = rtY_Right.DC_phaC;
|
||||
|
||||
RIGHT_TIM->CCR1 = (uint16_t)CLAMP((ur + pwm_res / 2), PWM_MARGIN, pwm_res - PWM_MARGIN);
|
||||
RIGHT_TIM->CCR2 = (uint16_t)CLAMP((vr + pwm_res / 2), PWM_MARGIN, pwm_res - PWM_MARGIN);
|
||||
RIGHT_TIM->CCR3 = (uint16_t)CLAMP((wr + pwm_res / 2), PWM_MARGIN, pwm_res - PWM_MARGIN);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,56 @@
|
||||
#ifndef BLDC_DEFS_H
|
||||
#define BLDC_DEFS_H
|
||||
|
||||
#include "stm32h7xx.h" // For GPIO_TypeDef
|
||||
|
||||
#define COM_CTRL 0 // [-] Commutation Control Type
|
||||
#define SIN_CTRL 1 // [-] Sinusoidal Control Type
|
||||
#define FOC_CTRL 2 // [-] Field Oriented Control (FOC) Type
|
||||
|
||||
#define LEFT_TIM TIM8
|
||||
#define RIGHT_TIM TIM1
|
||||
|
||||
#define PWM_FREQ 32000
|
||||
#define PWM_MARGIN 100
|
||||
#define CF_SPEED_COEF (PWM_FREQ / 3)
|
||||
#define MAX_RPM 1000
|
||||
#define RPM_TO_UNIT 16
|
||||
#define RPM_DEADBAND 1
|
||||
|
||||
#define BODY_MOTOR_LEFT 1U
|
||||
#define BODY_MOTOR_RIGHT 2U
|
||||
|
||||
// Stall detection recovery time. Time to wait after a stall before re-enabling controls.
|
||||
#define STALL_DEQUAL_TIME_MS 3000
|
||||
#define T_ERR_DEQUAL_CYCLES (uint16_t)(STALL_DEQUAL_TIME_MS * (PWM_FREQ / 2) / 1000)
|
||||
|
||||
// Motor
|
||||
#define I_DC_MAX 6
|
||||
#define I_MOT_MAX 6
|
||||
#define A2BIT_CONV 310
|
||||
#define N_MOT_MAX 1000
|
||||
|
||||
// Control selections
|
||||
#define CTRL_TYP_SEL FOC_CTRL // [-] Control type selection: COM_CTRL, SIN_CTRL, FOC_CTRL (default)
|
||||
#define CTRL_MOD_REQ SPD_MODE // [-] Control mode request: OPEN_MODE, VLT_MODE (default), SPD_MODE, TRQ_MODE. Note: SPD_MODE and TRQ_MODE are only available for CTRL_FOC!
|
||||
#define DIAG_ENA 1 // [-] Motor Diagnostics enable flag: 0 = Disabled, 1 = Enabled (default)
|
||||
|
||||
// Field Weakening / Phase Advance
|
||||
#define FIELD_WEAK_ENA 1 // [-] Field Weakening / Phase Advance enable flag: 0 = Disabled (default), 1 = Enabled
|
||||
#define FIELD_WEAK_MAX 5 // [A] Maximum Field Weakening D axis current (only for FOC).
|
||||
#define PHASE_ADV_MAX 25 // [deg] Maximum Phase Advance angle (only for SIN).
|
||||
#define FIELD_WEAK_HI 1000 // Input target High threshold
|
||||
#define FIELD_WEAK_LO 750 // Input target Low threshold
|
||||
|
||||
// Battery configuration
|
||||
#define BAT_CELLS 3 // 3 sets in series
|
||||
#define BAT_CELL_FULL_MV 4200U // mV per cell at 100%
|
||||
#define BAT_CELL_EMPTY_MV 3386U // mV per cell at 0% (from V1: 4200 - 100 * 8.14)
|
||||
#define VOLTS_PER_PERCENT 0.00814 // Volts per percent, for conversion of volts to percentage
|
||||
#define BAT_CALIB_REAL_VOLTAGE 1260U // multimeter voltage
|
||||
#define BAT_CALIB_ADC 1275U // adc reading voltage
|
||||
|
||||
void bldc_init(void);
|
||||
void bldc_step(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* File: rtwtypes.h
|
||||
*
|
||||
* Code generated for Simulink model 'BLDC_controller'.
|
||||
*
|
||||
* Model version : 1.1297
|
||||
* Simulink Coder version : 8.13 (R2017b) 24-Jul-2017
|
||||
* C/C++ source code generated on : Sun Mar 6 11:02:11 2022
|
||||
*
|
||||
* Target selection: ert.tlc
|
||||
* Embedded hardware selection: ARM Compatible->ARM Cortex
|
||||
* Emulation hardware selection:
|
||||
* Differs from embedded hardware (MATLAB Host)
|
||||
* Code generation objectives:
|
||||
* 1. Execution efficiency
|
||||
* 2. RAM efficiency
|
||||
* Validation result: Not run
|
||||
*/
|
||||
|
||||
#ifndef RTWTYPES_H
|
||||
#define RTWTYPES_H
|
||||
|
||||
/* Logical type definitions */
|
||||
#if (!defined(__cplusplus))
|
||||
# ifndef false
|
||||
# define false (0U)
|
||||
# endif
|
||||
|
||||
# ifndef true
|
||||
# define true (1U)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*=======================================================================*
|
||||
* Target hardware information
|
||||
* Device type: MATLAB Host
|
||||
* Number of bits: char: 8 short: 16 int: 32
|
||||
* long: 32 long long: 64
|
||||
* native word size: 64
|
||||
* Byte ordering: LittleEndian
|
||||
* Signed integer division rounds to: Zero
|
||||
* Shift right on a signed integer as arithmetic shift: on
|
||||
*=======================================================================*/
|
||||
|
||||
/*=======================================================================*
|
||||
* Fixed width word size data types: *
|
||||
* int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers *
|
||||
* uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers *
|
||||
* real32_T, real64_T - 32 and 64 bit floating point numbers *
|
||||
*=======================================================================*/
|
||||
typedef signed char int8_T;
|
||||
typedef unsigned char uint8_T;
|
||||
typedef short int16_T;
|
||||
typedef unsigned short uint16_T;
|
||||
typedef int int32_T;
|
||||
typedef unsigned int uint32_T;
|
||||
typedef long long int64_T;
|
||||
typedef unsigned long long uint64_T;
|
||||
typedef float real32_T;
|
||||
typedef double real64_T;
|
||||
|
||||
/*===========================================================================*
|
||||
* Generic type definitions: boolean_T, char_T, byte_T, int_T, uint_T, *
|
||||
* real_T, time_T, ulong_T, ulonglong_T. *
|
||||
*===========================================================================*/
|
||||
typedef double real_T;
|
||||
typedef double time_T;
|
||||
typedef unsigned char boolean_T;
|
||||
typedef int int_T;
|
||||
typedef unsigned int uint_T;
|
||||
typedef unsigned long ulong_T;
|
||||
typedef unsigned long long ulonglong_T;
|
||||
typedef char char_T;
|
||||
typedef unsigned char uchar_T;
|
||||
typedef char_T byte_T;
|
||||
|
||||
/*=======================================================================*
|
||||
* Min and Max: *
|
||||
* int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers *
|
||||
* uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers *
|
||||
*=======================================================================*/
|
||||
#define MAX_int8_T ((int8_T)(127))
|
||||
#define MIN_int8_T ((int8_T)(-128))
|
||||
#define MAX_uint8_T ((uint8_T)(255U))
|
||||
#define MAX_int16_T ((int16_T)(32767))
|
||||
#define MIN_int16_T ((int16_T)(-32768))
|
||||
#define MAX_uint16_T ((uint16_T)(65535U))
|
||||
#define MAX_int32_T ((int32_T)(2147483647))
|
||||
#define MIN_int32_T ((int32_T)(-2147483647-1))
|
||||
#define MAX_uint32_T ((uint32_T)(0xFFFFFFFFU))
|
||||
#define MAX_int64_T ((int64_T)(9223372036854775807LL))
|
||||
#define MIN_int64_T ((int64_T)(-9223372036854775807LL-1LL))
|
||||
#define MAX_uint64_T ((uint64_T)(0xFFFFFFFFFFFFFFFFULL))
|
||||
|
||||
/* Block D-Work pointer type */
|
||||
typedef void * pointer_T;
|
||||
|
||||
#endif /* RTWTYPES_H */
|
||||
|
||||
/*
|
||||
* File trailer for generated code.
|
||||
*
|
||||
* [EOF]
|
||||
*/
|
||||
@@ -0,0 +1,46 @@
|
||||
#include "board/body/boards/board_declarations.h"
|
||||
|
||||
void board_body_init(void) {
|
||||
// Initialize CAN pins
|
||||
set_gpio_pullup(CAN_RX_PORT, CAN_RX_PIN, PULL_NONE);
|
||||
set_gpio_alternate(CAN_RX_PORT, CAN_RX_PIN, GPIO_AF9_FDCAN1);
|
||||
set_gpio_pullup(CAN_TX_PORT, CAN_TX_PIN, PULL_NONE);
|
||||
set_gpio_alternate(CAN_TX_PORT, CAN_TX_PIN, GPIO_AF9_FDCAN1);
|
||||
|
||||
// Initialize button input (PC15)
|
||||
set_gpio_mode(IGNITION_SW_PORT, IGNITION_SW_PIN, MODE_INPUT);
|
||||
SYSCFG->EXTICR[3] &= ~(SYSCFG_EXTICR4_EXTI15);
|
||||
SYSCFG->EXTICR[3] |= SYSCFG_EXTICR4_EXTI15_PC;
|
||||
EXTI->PR1 = (1U << 15);
|
||||
EXTI->RTSR1 |= (1U << 15);
|
||||
EXTI->FTSR1 |= (1U << 15);
|
||||
EXTI->IMR1 |= (1U << 15);
|
||||
|
||||
// Initialize barrel jack detection input (PC13)
|
||||
set_gpio_pullup(CHARGING_DETECT_PORT, CHARGING_DETECT_PIN, PULL_UP);
|
||||
set_gpio_mode(CHARGING_DETECT_PORT, CHARGING_DETECT_PIN, MODE_INPUT);
|
||||
SYSCFG->EXTICR[3] &= ~(SYSCFG_EXTICR4_EXTI13);
|
||||
SYSCFG->EXTICR[3] |= SYSCFG_EXTICR4_EXTI13_PC;
|
||||
EXTI->PR1 = (1U << 13);
|
||||
EXTI->RTSR1 |= (1U << 13);
|
||||
EXTI->FTSR1 |= (1U << 13);
|
||||
EXTI->IMR1 |= (1U << 13);
|
||||
|
||||
// Initialize and turn on mici power
|
||||
set_gpio_mode(OBDC_POWER_ON_PORT, OBDC_POWER_ON_PIN, MODE_OUTPUT);
|
||||
set_gpio_output(OBDC_POWER_ON_PORT, OBDC_POWER_ON_PIN, 1);
|
||||
|
||||
// Initialize and turn off gpu power
|
||||
set_gpio_mode(GPU_POWER_ON_PORT, GPU_POWER_ON_PIN, MODE_OUTPUT);
|
||||
set_gpio_output(GPU_POWER_ON_PORT, GPU_POWER_ON_PIN, 0);
|
||||
|
||||
// Initialize and turn off ignition output
|
||||
set_gpio_mode(OBDC_IGNITION_ON_PORT, OBDC_IGNITION_ON_PIN, MODE_OUTPUT);
|
||||
set_gpio_output(OBDC_IGNITION_ON_PORT, OBDC_IGNITION_ON_PIN, 0);
|
||||
}
|
||||
|
||||
board board_body = {
|
||||
.led_GPIO = {GPIOA, GPIOA, GPIOA},
|
||||
.led_pin = {10, 10, 10},
|
||||
.init = board_body_init,
|
||||
};
|
||||
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "board/body/bldc/bldc_defs.h"
|
||||
|
||||
// ******************** Prototypes ********************
|
||||
typedef void (*board_init)(void);
|
||||
typedef void (*board_init_bootloader)(void);
|
||||
typedef void (*board_enable_can_transceiver)(uint8_t transceiver, bool enabled);
|
||||
|
||||
struct board {
|
||||
GPIO_TypeDef * const led_GPIO[3];
|
||||
const uint8_t led_pin[3];
|
||||
const uint8_t led_pwm_channels[3]; // leave at 0 to disable PWM
|
||||
board_init init;
|
||||
board_init_bootloader init_bootloader;
|
||||
const bool has_spi;
|
||||
};
|
||||
|
||||
// ******************* Definitions ********************
|
||||
#define HW_TYPE_BODY 0xB1U
|
||||
|
||||
// Pin definitions
|
||||
// CAN
|
||||
#define CAN_TX_PORT GPIOD
|
||||
#define CAN_TX_PIN 1
|
||||
#define CAN_RX_PORT GPIOD
|
||||
#define CAN_RX_PIN 0
|
||||
#define CAN_TRANSCEIVER_EN_PORT GPIOD
|
||||
#define CAN_TRANSCEIVER_EN_PIN 12
|
||||
|
||||
// Ignition and charging detection
|
||||
#define IGNITION_SW_PORT GPIOC
|
||||
#define IGNITION_SW_PIN 15
|
||||
#define CHARGING_DETECT_PORT GPIOC
|
||||
#define CHARGING_DETECT_PIN 13
|
||||
|
||||
// Dotstar LED
|
||||
#define DOTSTAR_CLK_PORT GPIOB
|
||||
#define DOTSTAR_CLK_PIN 3
|
||||
#define DOTSTAR_DATA_PORT GPIOB
|
||||
#define DOTSTAR_DATA_PIN 5
|
||||
|
||||
// Mici Power On
|
||||
#define OBDC_POWER_ON_PORT GPIOB
|
||||
#define OBDC_POWER_ON_PIN 12
|
||||
|
||||
// GPU Power On
|
||||
#define GPU_POWER_ON_PORT GPIOD
|
||||
#define GPU_POWER_ON_PIN 8
|
||||
|
||||
// Ignition On
|
||||
#define OBDC_IGNITION_ON_PORT GPIOB
|
||||
#define OBDC_IGNITION_ON_PIN 11
|
||||
@@ -0,0 +1,118 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "board/can.h"
|
||||
#include "board/health.h"
|
||||
#include "board/body/boards/board_declarations.h"
|
||||
#include "board/drivers/drivers.h"
|
||||
#include "opendbc/safety/declarations.h"
|
||||
#include "board/body/bldc/bldc.h"
|
||||
|
||||
#define BODY_CAN_ADDR_MOTOR_SPEED 0x201U
|
||||
#define BODY_CAN_ADDR_VAR_VALUES 0x202U
|
||||
#define BODY_CAN_ADDR_BODY_DATA 0x203U
|
||||
#define BODY_CAN_ADDR_V2_ID 0x222U
|
||||
#define BODY_CAN_MOTOR_SPEED_PERIOD_US 10000U
|
||||
#define BODY_CAN_CMD_TIMEOUT_US 100000U
|
||||
#define BODY_BUS_NUMBER 0U
|
||||
|
||||
static uint32_t last_can_cmd_timestamp_us = 0U;
|
||||
static uint16_t counter = 0U;
|
||||
|
||||
void body_can_send_motor_speeds(uint8_t bus, float left_speed_rpm, float right_speed_rpm) {
|
||||
CANPacket_t pkt = {0};
|
||||
pkt.bus = bus;
|
||||
pkt.addr = BODY_CAN_ADDR_MOTOR_SPEED;
|
||||
pkt.data_len_code = 8;
|
||||
int16_t left_speed_deci = left_speed_rpm;
|
||||
int16_t right_speed_deci = -(right_speed_rpm);
|
||||
pkt.data[0] = (uint8_t)((left_speed_deci >> 8) & 0xFFU);
|
||||
pkt.data[1] = (uint8_t)(left_speed_deci & 0xFFU);
|
||||
pkt.data[2] = (uint8_t)((right_speed_deci >> 8) & 0xFFU);
|
||||
pkt.data[3] = (uint8_t)(right_speed_deci & 0xFFU);
|
||||
pkt.data[4] = 0U;
|
||||
pkt.data[5] = 0U;
|
||||
pkt.data[6] = counter & 0xFFU;
|
||||
can_set_checksum(&pkt);
|
||||
can_send(&pkt, bus, true);
|
||||
counter++;
|
||||
}
|
||||
|
||||
void body_can_send_var_values(uint8_t bus, bool ignition, bool enable_motors, uint8_t fault, uint8_t left_z_errcode, uint8_t right_z_errcode) {
|
||||
CANPacket_t pkt = {0};
|
||||
pkt.bus = bus;
|
||||
pkt.addr = BODY_CAN_ADDR_VAR_VALUES;
|
||||
pkt.data_len_code = 3;
|
||||
pkt.data[0] = (ignition ? 1U : 0U) | ((enable_motors ? 1U : 0U) << 1U) | ((fault & 0x3FU) << 2U);
|
||||
pkt.data[1] = left_z_errcode;
|
||||
pkt.data[2] = right_z_errcode;
|
||||
can_set_checksum(&pkt);
|
||||
can_send(&pkt, bus, true);
|
||||
}
|
||||
|
||||
void body_can_send_body_data(uint8_t bus, uint8_t mcu_temp_raw, uint16_t batt_voltage_raw, uint8_t batt_percentage, bool charger_connected) {
|
||||
CANPacket_t pkt = {0};
|
||||
pkt.bus = bus;
|
||||
pkt.addr = BODY_CAN_ADDR_BODY_DATA;
|
||||
pkt.data_len_code = 4;
|
||||
pkt.data[0] = mcu_temp_raw;
|
||||
pkt.data[1] = (uint8_t)((batt_voltage_raw >> 8) & 0xFFU);
|
||||
pkt.data[2] = (uint8_t)(batt_voltage_raw & 0xFFU);
|
||||
pkt.data[3] = (charger_connected ? 1U : 0U) | ((batt_percentage & 0x7FU) << 1U);
|
||||
can_set_checksum(&pkt);
|
||||
can_send(&pkt, bus, true);
|
||||
}
|
||||
|
||||
void body_can_process_target(int16_t left_target_deci_rpm, int16_t right_target_deci_rpm) {
|
||||
rpm_left = (int)(((float)left_target_deci_rpm) * 0.1f);
|
||||
rpm_right = (int)(((float)right_target_deci_rpm) * 0.1f);
|
||||
last_can_cmd_timestamp_us = microsecond_timer_get();
|
||||
}
|
||||
|
||||
void body_can_rx(CANPacket_t *msg) {
|
||||
if ((msg->addr == 0x250U) && (GET_LEN(msg) >= 4U)) {
|
||||
int16_t left_target_deci_rpm = (int16_t)((msg->data[0] << 8U) | msg->data[1]);
|
||||
int16_t right_target_deci_rpm = (int16_t)((msg->data[2] << 8U) | msg->data[3]);
|
||||
body_can_process_target(left_target_deci_rpm, right_target_deci_rpm);
|
||||
}
|
||||
}
|
||||
|
||||
void body_can_init(void) {
|
||||
last_can_cmd_timestamp_us = 0U;
|
||||
can_silent = false;
|
||||
can_loopback = false;
|
||||
(void)set_safety_hooks(SAFETY_BODY, 0U);
|
||||
set_gpio_output(CAN_TRANSCEIVER_EN_PORT, CAN_TRANSCEIVER_EN_PIN, 0); // Enable CAN transceiver
|
||||
can_init_all();
|
||||
}
|
||||
|
||||
void body_can_periodic(uint32_t now, bool ignition, bool plug_charging) {
|
||||
if ((last_can_cmd_timestamp_us != 0U) &&
|
||||
((now - last_can_cmd_timestamp_us) >= BODY_CAN_CMD_TIMEOUT_US)) {
|
||||
rpm_left = 0;
|
||||
rpm_right = 0;
|
||||
last_can_cmd_timestamp_us = 0U;
|
||||
}
|
||||
|
||||
static uint32_t last_motor_speed_tx_us = 0;
|
||||
if ((now - last_motor_speed_tx_us) >= BODY_CAN_MOTOR_SPEED_PERIOD_US) {
|
||||
float left_speed_rpm = motor_encoder_get_speed_rpm(BODY_MOTOR_LEFT);
|
||||
float right_speed_rpm = motor_encoder_get_speed_rpm(BODY_MOTOR_RIGHT);
|
||||
body_can_send_motor_speeds(BODY_BUS_NUMBER, left_speed_rpm, right_speed_rpm);
|
||||
body_can_send_var_values(BODY_BUS_NUMBER, ignition, enable_motors, 0U, rtY_Left.z_errCode, rtY_Right.z_errCode);
|
||||
body_can_send_body_data(BODY_BUS_NUMBER, 0U, batt_voltage_raw, batt_percentage, plug_charging);
|
||||
|
||||
// Send message on 0x222 to identify as body v2
|
||||
CANPacket_t id_pkt = {0};
|
||||
id_pkt.bus = BODY_BUS_NUMBER;
|
||||
id_pkt.addr = BODY_CAN_ADDR_V2_ID;
|
||||
id_pkt.data_len_code = 1;
|
||||
id_pkt.data[0] = 1U;
|
||||
can_set_checksum(&id_pkt);
|
||||
can_send(&id_pkt, BODY_BUS_NUMBER, true);
|
||||
|
||||
last_motor_speed_tx_us = now;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "board/config.h"
|
||||
#include "board/body/boards/board_declarations.h"
|
||||
|
||||
#define DOTSTAR_LED_COUNT 10U
|
||||
#define DOTSTAR_GLOBAL_BRIGHTNESS_MAX 31U
|
||||
|
||||
typedef struct {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
} dotstar_rgb_t;
|
||||
|
||||
typedef struct {
|
||||
bool initialized;
|
||||
uint8_t global_brightness;
|
||||
dotstar_rgb_t pixels[DOTSTAR_LED_COUNT];
|
||||
} dotstar_state_t;
|
||||
|
||||
static dotstar_state_t dotstar_state = {
|
||||
.initialized = false,
|
||||
.global_brightness = DOTSTAR_GLOBAL_BRIGHTNESS_MAX,
|
||||
};
|
||||
|
||||
static inline void dotstar_set_clk(bool high) {
|
||||
if (high) {
|
||||
DOTSTAR_CLK_PORT->BSRR = (uint32_t)(1U << DOTSTAR_CLK_PIN);
|
||||
} else {
|
||||
DOTSTAR_CLK_PORT->BSRR = (uint32_t)(1U << (DOTSTAR_CLK_PIN + 16U));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void dotstar_set_data(bool high) {
|
||||
if (high) {
|
||||
DOTSTAR_DATA_PORT->BSRR = (uint32_t)(1U << DOTSTAR_DATA_PIN);
|
||||
} else {
|
||||
DOTSTAR_DATA_PORT->BSRR = (uint32_t)(1U << (DOTSTAR_DATA_PIN + 16U));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void dotstar_write_byte(uint8_t value) {
|
||||
for (int8_t bit = 7; bit >= 0; bit--) {
|
||||
dotstar_set_data(((value >> bit) & 0x1U) != 0U);
|
||||
delay(15);
|
||||
dotstar_set_clk(true);
|
||||
delay(15);
|
||||
dotstar_set_clk(false);
|
||||
delay(15);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint16_t dotstar_latch_len(uint16_t led_count) {
|
||||
uint16_t len = (uint16_t)((led_count + 15U) / 16U);
|
||||
if (len < led_count) {
|
||||
len = led_count;
|
||||
}
|
||||
return (len < 4U) ? 4U : len;
|
||||
}
|
||||
|
||||
static inline void dotstar_send_start_frame(void) {
|
||||
for (uint8_t i = 0U; i < 4U; i++) {
|
||||
dotstar_write_byte(0x00U);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void dotstar_send_end_frame(uint16_t led_count) {
|
||||
uint16_t latch_len = dotstar_latch_len(led_count);
|
||||
for (uint16_t i = 0U; i < latch_len; i++) {
|
||||
dotstar_write_byte(0xFFU);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void dotstar_show(void) {
|
||||
if (!dotstar_state.initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
dotstar_send_start_frame();
|
||||
|
||||
uint8_t prefix = (uint8_t)(0xE0U | dotstar_state.global_brightness);
|
||||
for (uint16_t i = 0U; i < DOTSTAR_LED_COUNT; i++) {
|
||||
dotstar_rgb_t *pixel = &dotstar_state.pixels[i];
|
||||
dotstar_write_byte(prefix);
|
||||
dotstar_write_byte(pixel->b);
|
||||
dotstar_write_byte(pixel->g);
|
||||
dotstar_write_byte(pixel->r);
|
||||
}
|
||||
|
||||
dotstar_send_end_frame(DOTSTAR_LED_COUNT);
|
||||
}
|
||||
|
||||
static inline void dotstar_init(void) {
|
||||
set_gpio_pullup(DOTSTAR_CLK_PORT, DOTSTAR_CLK_PIN, PULL_NONE);
|
||||
set_gpio_output_type(DOTSTAR_CLK_PORT, DOTSTAR_CLK_PIN, OUTPUT_TYPE_PUSH_PULL);
|
||||
set_gpio_mode(DOTSTAR_CLK_PORT, DOTSTAR_CLK_PIN, MODE_OUTPUT);
|
||||
register_set(&(DOTSTAR_CLK_PORT->OSPEEDR), GPIO_OSPEEDR_OSPEED5, GPIO_OSPEEDR_OSPEED5_Msk);
|
||||
dotstar_set_clk(false);
|
||||
|
||||
set_gpio_pullup(DOTSTAR_DATA_PORT, DOTSTAR_DATA_PIN, PULL_NONE);
|
||||
set_gpio_output_type(DOTSTAR_DATA_PORT, DOTSTAR_DATA_PIN, OUTPUT_TYPE_PUSH_PULL);
|
||||
set_gpio_mode(DOTSTAR_DATA_PORT, DOTSTAR_DATA_PIN, MODE_OUTPUT);
|
||||
register_set(&(DOTSTAR_DATA_PORT->OSPEEDR), GPIO_OSPEEDR_OSPEED5, GPIO_OSPEEDR_OSPEED5_Msk);
|
||||
dotstar_set_data(false);
|
||||
|
||||
dotstar_state.initialized = true;
|
||||
dotstar_state.global_brightness = DOTSTAR_GLOBAL_BRIGHTNESS_MAX;
|
||||
|
||||
for (uint16_t i = 0U; i < DOTSTAR_LED_COUNT; i++) {
|
||||
dotstar_state.pixels[i].r = 0U;
|
||||
dotstar_state.pixels[i].g = 0U;
|
||||
dotstar_state.pixels[i].b = 0U;
|
||||
}
|
||||
|
||||
dotstar_show();
|
||||
}
|
||||
|
||||
static inline void dotstar_set_pixel(uint16_t index, uint8_t r, uint8_t g, uint8_t b) {
|
||||
if (!dotstar_state.initialized || (index >= DOTSTAR_LED_COUNT)) {
|
||||
return;
|
||||
}
|
||||
dotstar_state.pixels[index].r = r;
|
||||
dotstar_state.pixels[index].g = g;
|
||||
dotstar_state.pixels[index].b = b;
|
||||
}
|
||||
|
||||
static inline void dotstar_fill(uint8_t r, uint8_t g, uint8_t b) {
|
||||
if (!dotstar_state.initialized) {
|
||||
return;
|
||||
}
|
||||
for (uint16_t i = 0U; i < DOTSTAR_LED_COUNT; i++) {
|
||||
dotstar_state.pixels[i].r = r;
|
||||
dotstar_state.pixels[i].g = g;
|
||||
dotstar_state.pixels[i].b = b;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void dotstar_set_global_brightness(uint8_t brightness) {
|
||||
dotstar_state.global_brightness = (brightness > DOTSTAR_GLOBAL_BRIGHTNESS_MAX) ? DOTSTAR_GLOBAL_BRIGHTNESS_MAX : brightness;
|
||||
}
|
||||
|
||||
static inline void dotstar_hue_to_rgb(uint16_t hue, uint8_t *r, uint8_t *g, uint8_t *b) {
|
||||
hue %= 765U;
|
||||
if (hue < 255U) {
|
||||
*r = (uint8_t)(255U - hue);
|
||||
*g = (uint8_t)hue;
|
||||
*b = 0U;
|
||||
} else if (hue < 510U) {
|
||||
hue -= 255U;
|
||||
*r = 0U;
|
||||
*g = (uint8_t)(255U - hue);
|
||||
*b = (uint8_t)hue;
|
||||
} else {
|
||||
hue -= 510U;
|
||||
*r = (uint8_t)hue;
|
||||
*g = 0U;
|
||||
*b = (uint8_t)(255U - hue);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void dotstar_run_rainbow(uint32_t now_us) {
|
||||
uint32_t brightness_phase = (now_us / 40000U) % 62U;
|
||||
uint8_t brightness = (brightness_phase <= 31U) ? (uint8_t)(brightness_phase + 1U) : (uint8_t)(62U - brightness_phase);
|
||||
if (brightness == 0U) {
|
||||
brightness = 1U;
|
||||
}
|
||||
dotstar_set_global_brightness(brightness);
|
||||
|
||||
uint32_t base_hue = (now_us / 10000U) % 765U;
|
||||
for (uint16_t i = 0U; i < DOTSTAR_LED_COUNT; i++) {
|
||||
uint16_t hue = (uint16_t)((base_hue + (i * 70U)) % 765U);
|
||||
uint8_t r, g, b;
|
||||
dotstar_hue_to_rgb(hue, &r, &g, &b);
|
||||
dotstar_set_pixel(i, r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void dotstar_apply_breathe(dotstar_rgb_t color, uint32_t now_us, uint32_t cycle_us) {
|
||||
if (!dotstar_state.initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cycle_us == 0U) {
|
||||
dotstar_set_global_brightness(DOTSTAR_GLOBAL_BRIGHTNESS_MAX);
|
||||
dotstar_fill(color.r, color.g, color.b);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t phase = now_us % cycle_us;
|
||||
uint32_t half_cycle = cycle_us / 2U;
|
||||
if (half_cycle == 0U) {
|
||||
half_cycle = 1U;
|
||||
}
|
||||
|
||||
uint32_t amplitude = (phase <= half_cycle) ? phase : (cycle_us - phase);
|
||||
uint32_t scale = (amplitude * 255U) / half_cycle;
|
||||
if (scale > 255U) {
|
||||
scale = 255U;
|
||||
}
|
||||
|
||||
uint8_t r = (uint8_t)((color.r * scale) / 255U);
|
||||
uint8_t g = (uint8_t)((color.g * scale) / 255U);
|
||||
uint8_t b = (uint8_t)((color.b * scale) / 255U);
|
||||
|
||||
dotstar_set_global_brightness(DOTSTAR_GLOBAL_BRIGHTNESS_MAX);
|
||||
dotstar_fill(r, g, b);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from panda import Panda
|
||||
|
||||
BODY_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||
BOARD_DIR = os.path.abspath(os.path.join(BODY_DIR, ".."))
|
||||
REPO_ROOT = os.path.abspath(os.path.join(BOARD_DIR, ".."))
|
||||
DEFAULT_FIRMWARE = os.path.join(BOARD_DIR, "obj", "body_h7.bin.signed")
|
||||
|
||||
|
||||
def build_body() -> None:
|
||||
subprocess.check_call(
|
||||
f"scons -C {REPO_ROOT} -j$(nproc) board/obj/body_h7.bin.signed",
|
||||
shell=True,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("firmware", nargs="?", help="Optional path to firmware binary to flash")
|
||||
parser.add_argument("--all", action="store_true", help="Flash all Panda devices")
|
||||
parser.add_argument(
|
||||
"--wait-usb",
|
||||
action="store_true",
|
||||
help="Wait for the panda to reconnect over USB after flashing (defaults to skipping reconnect).",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
firmware_path = os.path.abspath(args.firmware) if args.firmware is not None else DEFAULT_FIRMWARE
|
||||
|
||||
build_body()
|
||||
|
||||
if not os.path.isfile(firmware_path):
|
||||
parser.error(f"firmware file not found: {firmware_path}")
|
||||
|
||||
if args.all:
|
||||
serials = Panda.list()
|
||||
print(f"found {len(serials)} panda(s) - {serials}")
|
||||
else:
|
||||
serials = [None]
|
||||
|
||||
for s in serials:
|
||||
with Panda(serial=s) as p:
|
||||
print("flashing", p.get_usb_serial())
|
||||
p.flash(firmware_path, reconnect=args.wait_usb)
|
||||
exit(1 if len(serials) == 0 else 0)
|
||||
@@ -0,0 +1,144 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "board/config.h"
|
||||
#include "board/drivers/led.h"
|
||||
#include "board/drivers/pwm.h"
|
||||
#include "board/drivers/usb.h"
|
||||
#include "board/early_init.h"
|
||||
#include "board/obj/gitversion.h"
|
||||
#include "board/body/can.h"
|
||||
#include "opendbc/safety/safety.h"
|
||||
#include "board/drivers/can_common.h"
|
||||
#include "board/drivers/fdcan.h"
|
||||
#include "board/can_comms.h"
|
||||
#include "board/body/dotstar.h"
|
||||
#include "bldc/bldc.h"
|
||||
|
||||
extern int _app_start[0xc000];
|
||||
|
||||
#include "board/body/main_comms.h"
|
||||
|
||||
static volatile uint32_t tick_count = 0U;
|
||||
static volatile uint32_t ignition_press_timestamp_us = 0U;
|
||||
static volatile bool ignition = false;
|
||||
static volatile bool plug_charging = false;
|
||||
|
||||
void debug_ring_callback(uart_ring *ring) {
|
||||
char rcv;
|
||||
while (get_char(ring, &rcv)) {
|
||||
(void)injectc(ring, rcv);
|
||||
}
|
||||
}
|
||||
|
||||
void __attribute__ ((noinline)) enable_fpu(void) {
|
||||
SCB->CPACR |= ((3UL << (10U * 2U)) | (3UL << (11U * 2U)));
|
||||
}
|
||||
|
||||
void __initialize_hardware_early(void) {
|
||||
enable_fpu();
|
||||
early_initialization();
|
||||
}
|
||||
|
||||
void bldc_tim8_handler(void) {
|
||||
if ((LEFT_TIM->SR & TIM_SR_UIF) != 0) {
|
||||
LEFT_TIM->SR = ~TIM_SR_UIF;
|
||||
bldc_step();
|
||||
}
|
||||
}
|
||||
|
||||
void tick_handler(void) {
|
||||
if (TICK_TIMER->SR != 0) {
|
||||
if (can_health[0].transmit_error_cnt >= 128) {
|
||||
(void)llcan_init(CANIF_FROM_CAN_NUM(0));
|
||||
}
|
||||
static bool led_on = false;
|
||||
led_set(LED_RED, led_on);
|
||||
led_on = !led_on;
|
||||
tick_count++;
|
||||
}
|
||||
TICK_TIMER->SR = 0;
|
||||
}
|
||||
|
||||
static void exti15_10_handler(void) {
|
||||
if ((EXTI->PR1 & (1U << CHARGING_DETECT_PIN)) != 0U) {
|
||||
EXTI->PR1 = (1U << CHARGING_DETECT_PIN);
|
||||
plug_charging = (get_gpio_input(CHARGING_DETECT_PORT, CHARGING_DETECT_PIN) != 0);
|
||||
}
|
||||
|
||||
if ((EXTI->PR1 & (1U << IGNITION_SW_PIN)) != 0U) {
|
||||
EXTI->PR1 = (1U << IGNITION_SW_PIN);
|
||||
|
||||
static uint32_t last_press_event_us = 0U;
|
||||
const uint32_t debounce_us = 200000U; // 200 ms
|
||||
|
||||
uint32_t now = microsecond_timer_get();
|
||||
bool pressed = (get_gpio_input(IGNITION_SW_PORT, IGNITION_SW_PIN) == 0);
|
||||
|
||||
if (pressed) {
|
||||
if (get_ts_elapsed(now, last_press_event_us) > debounce_us) {
|
||||
last_press_event_us = now;
|
||||
ignition_press_timestamp_us = now;
|
||||
ignition = !ignition;
|
||||
set_gpio_output(OBDC_IGNITION_ON_PORT, OBDC_IGNITION_ON_PIN, ignition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
disable_interrupts();
|
||||
init_interrupts(true);
|
||||
|
||||
clock_init();
|
||||
peripherals_init();
|
||||
|
||||
current_board = &board_body;
|
||||
hw_type = HW_TYPE_BODY;
|
||||
|
||||
current_board->init();
|
||||
|
||||
REGISTER_INTERRUPT(EXTI15_10_IRQn, exti15_10_handler, 10000U, FAULT_INTERRUPT_RATE_EXTI);
|
||||
NVIC_ClearPendingIRQ(EXTI15_10_IRQn);
|
||||
NVIC_EnableIRQ(EXTI15_10_IRQn);
|
||||
|
||||
REGISTER_INTERRUPT(TIM8_UP_TIM13_IRQn, bldc_tim8_handler, 100000U, FAULT_INTERRUPT_RATE_TICK);
|
||||
NVIC_ClearPendingIRQ(TIM8_UP_TIM13_IRQn);
|
||||
NVIC_EnableIRQ(TIM8_UP_TIM13_IRQn);
|
||||
|
||||
REGISTER_INTERRUPT(TICK_TIMER_IRQ, tick_handler, 10U, FAULT_INTERRUPT_RATE_TICK);
|
||||
|
||||
led_init();
|
||||
microsecond_timer_init();
|
||||
tick_timer_init();
|
||||
usb_init();
|
||||
body_can_init();
|
||||
dotstar_init();
|
||||
bldc_init();
|
||||
enable_interrupts();
|
||||
|
||||
plug_charging = (get_gpio_input(CHARGING_DETECT_PORT, CHARGING_DETECT_PIN) != 0);
|
||||
|
||||
while (true) {
|
||||
uint32_t now = microsecond_timer_get();
|
||||
if (plug_charging) {
|
||||
motor_set_enable(false);
|
||||
dotstar_apply_breathe((dotstar_rgb_t){255U, 40U, 0U}, now, 2000000U);
|
||||
} else if (ignition) {
|
||||
dotstar_run_rainbow(now);
|
||||
} else {
|
||||
dotstar_apply_breathe((dotstar_rgb_t){0U, 255U, 10U}, now, 1500000U);
|
||||
}
|
||||
|
||||
if (ignition) {
|
||||
motor_set_enable(true);
|
||||
body_can_periodic(now, ignition, plug_charging);
|
||||
} else {
|
||||
motor_set_enable(false);
|
||||
}
|
||||
|
||||
dotstar_show();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
void comms_endpoint2_write(const uint8_t *data, uint32_t len) {
|
||||
UNUSED(data);
|
||||
UNUSED(len);
|
||||
}
|
||||
|
||||
int comms_control_handler(ControlPacket_t *req, uint8_t *resp) {
|
||||
unsigned int resp_len = 0;
|
||||
|
||||
switch (req->request) {
|
||||
// **** 0xc1: get hardware type
|
||||
case 0xc1:
|
||||
resp[0] = hw_type;
|
||||
resp_len = 1;
|
||||
break;
|
||||
|
||||
// **** 0xd1: enter bootloader mode
|
||||
case 0xd1:
|
||||
switch (req->param1) {
|
||||
case 0:
|
||||
print("-> entering bootloader\n");
|
||||
enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC;
|
||||
NVIC_SystemReset();
|
||||
break;
|
||||
case 1:
|
||||
print("-> entering softloader\n");
|
||||
enter_bootloader_mode = ENTER_SOFTLOADER_MAGIC;
|
||||
NVIC_SystemReset();
|
||||
break;
|
||||
default:
|
||||
print("Bootloader mode invalid\n");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// **** 0xd3/0xd4: signature bytes
|
||||
case 0xd3:
|
||||
case 0xd4: {
|
||||
uint8_t offset = (req->request == 0xd3) ? 0U : 64U;
|
||||
resp_len = 64U;
|
||||
char *code = (char *)_app_start;
|
||||
int code_len = _app_start[0];
|
||||
(void)memcpy(resp, &code[code_len + offset], resp_len);
|
||||
break;
|
||||
}
|
||||
|
||||
// **** 0xd6: get version
|
||||
case 0xd6:
|
||||
(void)memcpy(resp, gitversion, sizeof(gitversion));
|
||||
resp_len = sizeof(gitversion) - 1U;
|
||||
break;
|
||||
|
||||
// **** 0xd8: reset ST
|
||||
case 0xd8:
|
||||
NVIC_SystemReset();
|
||||
break;
|
||||
|
||||
// **** 0xdd: get healthpacket and CANPacket version hashes
|
||||
case 0xdd: {
|
||||
uint32_t versions[2] = {HEALTH_PACKET_VERSION, CAN_PACKET_VERSION_HASH};
|
||||
(void)memcpy(resp, (uint8_t *)versions, sizeof(versions));
|
||||
resp_len = sizeof(versions);
|
||||
break;
|
||||
}
|
||||
|
||||
// **** 0xb3: set motor speeds
|
||||
case 0xb3:
|
||||
rpm_left = (int16_t)req->param1;
|
||||
rpm_right = (int16_t)req->param2;
|
||||
break;
|
||||
|
||||
// **** 0xb4: enable/disable motors
|
||||
case 0xb4:
|
||||
enable_motors = (req->param1 == 1U);
|
||||
if (enable_motors == 0) {
|
||||
rpm_left = 0;
|
||||
rpm_right = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Ignore unhandled requests
|
||||
break;
|
||||
}
|
||||
return resp_len;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#include "board/body/boards/board_declarations.h"
|
||||
#include "board/body/boards/board_body.h"
|
||||
|
||||
extern board *current_board;
|
||||
extern uint8_t hw_type;
|
||||
|
||||
void detect_board_type(void) {
|
||||
// Board type set explicitly in main()
|
||||
}
|
||||
+11
-16
@@ -1,24 +1,22 @@
|
||||
#define BOOTSTUB
|
||||
|
||||
#define VERS_TAG 0x53524556
|
||||
#define MIN_VERSION 2
|
||||
|
||||
// ********************* Includes *********************
|
||||
#include "config.h"
|
||||
#include "board/config.h"
|
||||
|
||||
#include "drivers/led.h"
|
||||
#include "drivers/pwm.h"
|
||||
#include "drivers/usb.h"
|
||||
#include "board/drivers/led.h"
|
||||
#include "board/drivers/pwm.h"
|
||||
#include "board/drivers/usb.h"
|
||||
|
||||
#include "early_init.h"
|
||||
#include "provision.h"
|
||||
#include "board/early_init.h"
|
||||
#include "board/provision.h"
|
||||
|
||||
#include "crypto/rsa.h"
|
||||
#include "crypto/sha.h"
|
||||
#include "board/crypto/rsa.h"
|
||||
#include "board/crypto/sha.h"
|
||||
|
||||
#include "obj/cert.h"
|
||||
#include "obj/gitversion.h"
|
||||
#include "flasher.h"
|
||||
#include "board/obj/cert.h"
|
||||
#include "board/obj/gitversion.h"
|
||||
#include "board/flasher.h"
|
||||
|
||||
// cppcheck-suppress unusedFunction ; used in headers not included in cppcheck
|
||||
void __initialize_hardware_early(void) {
|
||||
@@ -32,9 +30,6 @@ void fail(void) {
|
||||
// know where to sig check
|
||||
extern void *_app_start[];
|
||||
|
||||
// FIXME: sometimes your panda will fail flashing and will quickly blink a single Green LED
|
||||
// BOUNTY: $200 coupon on shop.comma.ai or $100 check.
|
||||
|
||||
int main(void) {
|
||||
// Init interrupt table
|
||||
init_interrupts(true);
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
// ******************** Prototypes ********************
|
||||
void print(const char *a){ UNUSED(a); }
|
||||
void puth(uint8_t i){ UNUSED(i); }
|
||||
void puth2(uint8_t i){ UNUSED(i); }
|
||||
void puth4(uint8_t i){ UNUSED(i); }
|
||||
void puth(unsigned int i){ UNUSED(i); }
|
||||
void puth2(unsigned int i){ UNUSED(i); }
|
||||
__attribute__((unused)) static void puth4(unsigned int i){ UNUSED(i); }
|
||||
void hexdump(const void *a, int l){ UNUSED(a); UNUSED(l); }
|
||||
typedef struct board board;
|
||||
typedef struct harness_configuration harness_configuration;
|
||||
void pwm_init(TIM_TypeDef *TIM, uint8_t channel);
|
||||
void pwm_set(TIM_TypeDef *TIM, uint8_t channel, uint8_t percentage);
|
||||
// No UART support in bootloader
|
||||
typedef struct uart_ring {} uart_ring;
|
||||
uart_ring uart_ring_som_debug;
|
||||
typedef struct uart_ring uart_ring;
|
||||
void uart_init(uart_ring *q, int baud) { UNUSED(q); UNUSED(baud); }
|
||||
|
||||
// ********************* Globals **********************
|
||||
|
||||
@@ -3,6 +3,28 @@
|
||||
a certain number of CANPacket_t. The transaction is split
|
||||
into multiple transfers or chunks.
|
||||
|
||||
CAN packet byte layout (wire format used by comms_can_{read,write}):
|
||||
+--------+--------+--------+--------+--------+--------+--------+------------------------------+
|
||||
| byte 0 | byte 1 | byte 2 | byte 3 | byte 4 | byte 5 | byte 6 | ... byte 13 / byte 69 |
|
||||
+--------+--------+--------+--------+--------+--------+--------+------------------------------+
|
||||
| DLC | addr | addr | addr | flags | cksum | data0 | ... data7 / data63 |
|
||||
| bus | | | | | | | (classic CAN / CAN FD) |
|
||||
| fd | | | | | | | |
|
||||
+--------+--------+--------+--------+--------+--------+--------+------------------------------+
|
||||
Byte/bit fields:
|
||||
byte 0: DLC[7:4], bus[3:1], fd[0]
|
||||
bytes 1..4: (addr << 3) | (extended << 2) | (returned << 1) | rejected
|
||||
byte 5: checksum = XOR(header[0..4] + payload)
|
||||
bytes 6..13 (classic CAN, up to 8 bytes) / bytes 6..69 (CAN FD, up to 64 bytes): payload
|
||||
|
||||
USB/SPI transfer chunking used by this file:
|
||||
+--------------------------------------------+ ... +--------------------------------------------+
|
||||
| transport chunk 0 | | transport chunk N |
|
||||
+--------------------------------------------+ +--------------------------------------------+
|
||||
| concatenated CANPacket_t bytes | | continuation and/or next CANPacket_t bytes |
|
||||
| (no per-64-byte counter/header in protocol)| | |
|
||||
+--------------------------------------------+ +--------------------------------------------+
|
||||
|
||||
* comms_can_read outputs this buffer in chunks of a specified length.
|
||||
chunks are always the given length, except the last one.
|
||||
* comms_can_write reads in this buffer in chunks.
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// bump this when changing the CAN packet
|
||||
#define CAN_PACKET_VERSION 4
|
||||
|
||||
#define CANPACKET_HEAD_SIZE 6U
|
||||
|
||||
#if !defined(STM32F4)
|
||||
#define CANFD
|
||||
#define CANPACKET_DATA_SIZE_MAX 64U
|
||||
#else
|
||||
#define CANPACKET_DATA_SIZE_MAX 8U
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
unsigned char fd : 1;
|
||||
unsigned char bus : 3;
|
||||
unsigned char data_len_code : 4; // lookup length with dlc_to_len
|
||||
unsigned char rejected : 1;
|
||||
unsigned char returned : 1;
|
||||
unsigned char extended : 1;
|
||||
unsigned int addr : 29;
|
||||
unsigned char checksum;
|
||||
unsigned char data[CANPACKET_DATA_SIZE_MAX];
|
||||
} __attribute__((packed, aligned(4))) CANPacket_t;
|
||||
|
||||
#define GET_BUS(msg) ((msg)->bus)
|
||||
#define GET_LEN(msg) (dlc_to_len[(msg)->data_len_code])
|
||||
#define GET_ADDR(msg) ((msg)->addr)
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct {
|
||||
uint8_t request;
|
||||
uint16_t param1;
|
||||
|
||||
@@ -34,9 +34,7 @@
|
||||
|
||||
// platform includes
|
||||
#ifdef STM32H7
|
||||
#include "stm32h7/stm32h7_config.h"
|
||||
#elif defined(STM32F4)
|
||||
#include "stm32f4/stm32f4_config.h"
|
||||
#include "board/stm32h7/stm32h7_config.h"
|
||||
#else
|
||||
// TODO: uncomment this, cppcheck complains
|
||||
// building for tests
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(ENABLE_SPI) || defined(BOOTSTUB)
|
||||
uint8_t crc_checksum(const uint8_t *dat, int len, const uint8_t poly) {
|
||||
uint8_t crc = 0xFFU;
|
||||
int i;
|
||||
@@ -18,4 +17,3 @@ uint8_t crc_checksum(const uint8_t *dat, int len, const uint8_t poly) {
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// ********************* Critical section helpers *********************
|
||||
void enable_interrupts(void);
|
||||
void disable_interrupts(void);
|
||||
|
||||
extern uint8_t global_critical_depth;
|
||||
|
||||
#define ENTER_CRITICAL() \
|
||||
__disable_irq(); \
|
||||
global_critical_depth += 1U;
|
||||
|
||||
#define EXIT_CRITICAL() \
|
||||
global_critical_depth -= 1U; \
|
||||
if ((global_critical_depth == 0U) && interrupts_enabled) { \
|
||||
__enable_irq(); \
|
||||
}
|
||||
Regular → Executable
@@ -13,8 +13,6 @@ Make sure you're using a genuine one for boards that do not have a 3.3V panda po
|
||||
## Openocd
|
||||
Install openocd. For Ubuntu 24.04, the one in the package manager works fine: `sudo apt install openocd`.
|
||||
|
||||
To run, use `./debug_f4.sh (TODO)` or `./debug_h7.sh` depending on the panda.
|
||||
|
||||
## GDB
|
||||
You need `gdb-multiarch`.
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
set -e
|
||||
|
||||
DFU_UTIL="dfu-util"
|
||||
|
||||
scons -u -j$(nproc)
|
||||
|
||||
PYTHONPATH=.. python3 -c "from python import Panda; Panda().reset(enter_bootstub=True); Panda().reset(enter_bootloader=True)" || true
|
||||
sleep 1
|
||||
$DFU_UTIL -d 0483:df11 -a 0 -s 0x08004000 -D obj/panda.bin.signed
|
||||
$DFU_UTIL -d 0483:df11 -a 0 -s 0x08000000:leave -D obj/bootstub.panda.bin
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
set -e
|
||||
|
||||
DFU_UTIL="dfu-util"
|
||||
|
||||
scons -u -j$(nproc)
|
||||
|
||||
PYTHONPATH=.. python3 -c "from python import Panda; Panda().reset(enter_bootstub=True); Panda().reset(enter_bootloader=True)" || true
|
||||
sleep 1
|
||||
$DFU_UTIL -d 0483:df11 -a 0 -s 0x08004000 -D obj/panda.bin.signed
|
||||
$DFU_UTIL -d 0483:df11 -a 0 -s 0x08000000:leave -D obj/bootstub.panda.bin
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
set -e
|
||||
|
||||
DFU_UTIL="dfu-util"
|
||||
|
||||
scons -u -j$(nproc)
|
||||
|
||||
PYTHONPATH=.. python3 -c "from python import Panda; Panda().reset(enter_bootstub=True); Panda().reset(enter_bootloader=True)" || true
|
||||
sleep 1
|
||||
$DFU_UTIL -d 0483:df11 -a 0 -s 0x08020000 -D obj/panda_h7.bin.signed
|
||||
$DFU_UTIL -d 0483:df11 -a 0 -s 0x08000000:leave -D obj/bootstub.panda_h7.bin
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "bootkick_declarations.h"
|
||||
#include "board/drivers/drivers.h"
|
||||
|
||||
bool bootkick_reset_triggered = false;
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
extern bool bootkick_reset_triggered;
|
||||
|
||||
void bootkick_tick(bool ignition, bool recent_heartbeat);
|
||||
@@ -1,222 +0,0 @@
|
||||
#include "bxcan_declarations.h"
|
||||
|
||||
// IRQs: CAN1_TX, CAN1_RX0, CAN1_SCE
|
||||
// CAN2_TX, CAN2_RX0, CAN2_SCE
|
||||
// CAN3_TX, CAN3_RX0, CAN3_SCE
|
||||
|
||||
CAN_TypeDef *cans[CAN_ARRAY_SIZE] = {CAN1, CAN2, CAN3};
|
||||
uint8_t can_irq_number[CAN_IRQS_ARRAY_SIZE][CAN_IRQS_ARRAY_SIZE] = {
|
||||
{ CAN1_TX_IRQn, CAN1_RX0_IRQn, CAN1_SCE_IRQn },
|
||||
{ CAN2_TX_IRQn, CAN2_RX0_IRQn, CAN2_SCE_IRQn },
|
||||
{ CAN3_TX_IRQn, CAN3_RX0_IRQn, CAN3_SCE_IRQn },
|
||||
};
|
||||
|
||||
bool can_set_speed(uint8_t can_number) {
|
||||
bool ret = true;
|
||||
CAN_TypeDef *CANx = CANIF_FROM_CAN_NUM(can_number);
|
||||
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
|
||||
|
||||
ret &= llcan_set_speed(
|
||||
CANx,
|
||||
bus_config[bus_number].can_speed,
|
||||
can_loopback,
|
||||
(unsigned int)(can_silent) & (1U << can_number)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void can_clear_send(CAN_TypeDef *CANx, uint8_t can_number) {
|
||||
can_health[can_number].can_core_reset_cnt += 1U;
|
||||
llcan_clear_send(CANx);
|
||||
}
|
||||
|
||||
void update_can_health_pkt(uint8_t can_number, uint32_t ir_reg) {
|
||||
CAN_TypeDef *CANx = CANIF_FROM_CAN_NUM(can_number);
|
||||
uint32_t esr_reg = CANx->ESR;
|
||||
|
||||
can_health[can_number].bus_off = ((esr_reg & CAN_ESR_BOFF) >> CAN_ESR_BOFF_Pos);
|
||||
can_health[can_number].bus_off_cnt += can_health[can_number].bus_off;
|
||||
can_health[can_number].error_warning = ((esr_reg & CAN_ESR_EWGF) >> CAN_ESR_EWGF_Pos);
|
||||
can_health[can_number].error_passive = ((esr_reg & CAN_ESR_EPVF) >> CAN_ESR_EPVF_Pos);
|
||||
|
||||
can_health[can_number].last_error = ((esr_reg & CAN_ESR_LEC) >> CAN_ESR_LEC_Pos);
|
||||
if ((can_health[can_number].last_error != 0U) && (can_health[can_number].last_error != 7U)) {
|
||||
can_health[can_number].last_stored_error = can_health[can_number].last_error;
|
||||
}
|
||||
|
||||
can_health[can_number].receive_error_cnt = ((esr_reg & CAN_ESR_REC) >> CAN_ESR_REC_Pos);
|
||||
can_health[can_number].transmit_error_cnt = ((esr_reg & CAN_ESR_TEC) >> CAN_ESR_TEC_Pos);
|
||||
|
||||
can_health[can_number].irq0_call_rate = interrupts[can_irq_number[can_number][0]].call_rate;
|
||||
can_health[can_number].irq1_call_rate = interrupts[can_irq_number[can_number][1]].call_rate;
|
||||
can_health[can_number].irq2_call_rate = interrupts[can_irq_number[can_number][2]].call_rate;
|
||||
|
||||
if (ir_reg != 0U) {
|
||||
can_health[can_number].total_error_cnt += 1U;
|
||||
|
||||
// RX message lost due to FIFO overrun
|
||||
if ((CANx->RF0R & (CAN_RF0R_FOVR0)) != 0U) {
|
||||
can_health[can_number].total_rx_lost_cnt += 1U;
|
||||
CANx->RF0R &= ~(CAN_RF0R_FOVR0);
|
||||
}
|
||||
can_clear_send(CANx, can_number);
|
||||
}
|
||||
}
|
||||
|
||||
// ***************************** CAN *****************************
|
||||
// CANx_SCE IRQ Handler
|
||||
static void can_sce(uint8_t can_number) {
|
||||
update_can_health_pkt(can_number, 1U);
|
||||
}
|
||||
|
||||
// CANx_TX IRQ Handler
|
||||
void process_can(uint8_t can_number) {
|
||||
if (can_number != 0xffU) {
|
||||
|
||||
ENTER_CRITICAL();
|
||||
|
||||
CAN_TypeDef *CANx = CANIF_FROM_CAN_NUM(can_number);
|
||||
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
|
||||
|
||||
// check for empty mailbox
|
||||
CANPacket_t to_send;
|
||||
if ((CANx->TSR & (CAN_TSR_TERR0 | CAN_TSR_ALST0)) != 0U) { // last TX failed due to error arbitration lost
|
||||
can_health[can_number].total_tx_lost_cnt += 1U;
|
||||
CANx->TSR |= (CAN_TSR_TERR0 | CAN_TSR_ALST0);
|
||||
}
|
||||
if ((CANx->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) {
|
||||
// add successfully transmitted message to my fifo
|
||||
if ((CANx->TSR & CAN_TSR_RQCP0) == CAN_TSR_RQCP0) {
|
||||
if ((CANx->TSR & CAN_TSR_TXOK0) == CAN_TSR_TXOK0) {
|
||||
CANPacket_t to_push;
|
||||
to_push.fd = 0U;
|
||||
to_push.returned = 1U;
|
||||
to_push.rejected = 0U;
|
||||
to_push.extended = (CANx->sTxMailBox[0].TIR >> 2) & 0x1U;
|
||||
to_push.addr = (to_push.extended != 0U) ? (CANx->sTxMailBox[0].TIR >> 3) : (CANx->sTxMailBox[0].TIR >> 21);
|
||||
to_push.data_len_code = CANx->sTxMailBox[0].TDTR & 0xFU;
|
||||
to_push.bus = bus_number;
|
||||
WORD_TO_BYTE_ARRAY(&to_push.data[0], CANx->sTxMailBox[0].TDLR);
|
||||
WORD_TO_BYTE_ARRAY(&to_push.data[4], CANx->sTxMailBox[0].TDHR);
|
||||
can_set_checksum(&to_push);
|
||||
|
||||
rx_buffer_overflow += can_push(&can_rx_q, &to_push) ? 0U : 1U;
|
||||
}
|
||||
|
||||
// clear interrupt
|
||||
// careful, this can also be cleared by requesting a transmission
|
||||
CANx->TSR |= CAN_TSR_RQCP0;
|
||||
}
|
||||
|
||||
if (can_pop(can_queues[bus_number], &to_send)) {
|
||||
if (can_check_checksum(&to_send)) {
|
||||
can_health[can_number].total_tx_cnt += 1U;
|
||||
// only send if we have received a packet
|
||||
CANx->sTxMailBox[0].TIR = ((to_send.extended != 0U) ? (to_send.addr << 3) : (to_send.addr << 21)) | (to_send.extended << 2);
|
||||
CANx->sTxMailBox[0].TDTR = to_send.data_len_code;
|
||||
BYTE_ARRAY_TO_WORD(CANx->sTxMailBox[0].TDLR, &to_send.data[0]);
|
||||
BYTE_ARRAY_TO_WORD(CANx->sTxMailBox[0].TDHR, &to_send.data[4]);
|
||||
// Send request TXRQ
|
||||
CANx->sTxMailBox[0].TIR |= 0x1U;
|
||||
} else {
|
||||
can_health[can_number].total_tx_checksum_error_cnt += 1U;
|
||||
}
|
||||
|
||||
refresh_can_tx_slots_available();
|
||||
}
|
||||
}
|
||||
|
||||
EXIT_CRITICAL();
|
||||
}
|
||||
}
|
||||
|
||||
// CANx_RX0 IRQ Handler
|
||||
// blink blue when we are receiving CAN messages
|
||||
void can_rx(uint8_t can_number) {
|
||||
CAN_TypeDef *CANx = CANIF_FROM_CAN_NUM(can_number);
|
||||
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
|
||||
|
||||
while ((CANx->RF0R & CAN_RF0R_FMP0) != 0U) {
|
||||
can_health[can_number].total_rx_cnt += 1U;
|
||||
|
||||
// can is live
|
||||
pending_can_live = 1;
|
||||
|
||||
// add to my fifo
|
||||
CANPacket_t to_push;
|
||||
|
||||
to_push.fd = 0U;
|
||||
to_push.returned = 0U;
|
||||
to_push.rejected = 0U;
|
||||
to_push.extended = (CANx->sFIFOMailBox[0].RIR >> 2) & 0x1U;
|
||||
to_push.addr = (to_push.extended != 0U) ? (CANx->sFIFOMailBox[0].RIR >> 3) : (CANx->sFIFOMailBox[0].RIR >> 21);
|
||||
to_push.data_len_code = CANx->sFIFOMailBox[0].RDTR & 0xFU;
|
||||
to_push.bus = bus_number;
|
||||
WORD_TO_BYTE_ARRAY(&to_push.data[0], CANx->sFIFOMailBox[0].RDLR);
|
||||
WORD_TO_BYTE_ARRAY(&to_push.data[4], CANx->sFIFOMailBox[0].RDHR);
|
||||
can_set_checksum(&to_push);
|
||||
|
||||
// forwarding (panda only)
|
||||
int bus_fwd_num = safety_fwd_hook(bus_number, to_push.addr);
|
||||
if (bus_fwd_num != -1) {
|
||||
CANPacket_t to_send;
|
||||
|
||||
to_send.fd = 0U;
|
||||
to_send.returned = 0U;
|
||||
to_send.rejected = 0U;
|
||||
to_send.extended = to_push.extended; // TXRQ
|
||||
to_send.addr = to_push.addr;
|
||||
to_send.bus = to_push.bus;
|
||||
to_send.data_len_code = to_push.data_len_code;
|
||||
(void)memcpy(to_send.data, to_push.data, dlc_to_len[to_push.data_len_code]);
|
||||
can_set_checksum(&to_send);
|
||||
|
||||
can_send(&to_send, bus_fwd_num, true);
|
||||
can_health[can_number].total_fwd_cnt += 1U;
|
||||
}
|
||||
|
||||
safety_rx_invalid += safety_rx_hook(&to_push) ? 0U : 1U;
|
||||
ignition_can_hook(&to_push);
|
||||
|
||||
led_set(LED_BLUE, true);
|
||||
rx_buffer_overflow += can_push(&can_rx_q, &to_push) ? 0U : 1U;
|
||||
|
||||
// next
|
||||
CANx->RF0R |= CAN_RF0R_RFOM0;
|
||||
}
|
||||
}
|
||||
|
||||
static void CAN1_TX_IRQ_Handler(void) { process_can(0); }
|
||||
static void CAN1_RX0_IRQ_Handler(void) { can_rx(0); }
|
||||
static void CAN1_SCE_IRQ_Handler(void) { can_sce(0); }
|
||||
|
||||
static void CAN2_TX_IRQ_Handler(void) { process_can(1); }
|
||||
static void CAN2_RX0_IRQ_Handler(void) { can_rx(1); }
|
||||
static void CAN2_SCE_IRQ_Handler(void) { can_sce(1); }
|
||||
|
||||
static void CAN3_TX_IRQ_Handler(void) { process_can(2); }
|
||||
static void CAN3_RX0_IRQ_Handler(void) { can_rx(2); }
|
||||
static void CAN3_SCE_IRQ_Handler(void) { can_sce(2); }
|
||||
|
||||
bool can_init(uint8_t can_number) {
|
||||
bool ret = false;
|
||||
|
||||
REGISTER_INTERRUPT(CAN1_TX_IRQn, CAN1_TX_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_1)
|
||||
REGISTER_INTERRUPT(CAN1_RX0_IRQn, CAN1_RX0_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_1)
|
||||
REGISTER_INTERRUPT(CAN1_SCE_IRQn, CAN1_SCE_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_1)
|
||||
REGISTER_INTERRUPT(CAN2_TX_IRQn, CAN2_TX_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_2)
|
||||
REGISTER_INTERRUPT(CAN2_RX0_IRQn, CAN2_RX0_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_2)
|
||||
REGISTER_INTERRUPT(CAN2_SCE_IRQn, CAN2_SCE_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_2)
|
||||
REGISTER_INTERRUPT(CAN3_TX_IRQn, CAN3_TX_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_3)
|
||||
REGISTER_INTERRUPT(CAN3_RX0_IRQn, CAN3_RX0_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_3)
|
||||
REGISTER_INTERRUPT(CAN3_SCE_IRQn, CAN3_SCE_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_3)
|
||||
|
||||
if (can_number != 0xffU) {
|
||||
CAN_TypeDef *CANx = CANIF_FROM_CAN_NUM(can_number);
|
||||
ret &= can_set_speed(can_number);
|
||||
ret &= llcan_init(CANx);
|
||||
// in case there are queued up messages
|
||||
process_can(can_number);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// IRQs: CAN1_TX, CAN1_RX0, CAN1_SCE
|
||||
// CAN2_TX, CAN2_RX0, CAN2_SCE
|
||||
// CAN3_TX, CAN3_RX0, CAN3_SCE
|
||||
|
||||
#define CAN_ARRAY_SIZE 3
|
||||
#define CAN_IRQS_ARRAY_SIZE 3
|
||||
extern CAN_TypeDef *cans[CAN_ARRAY_SIZE];
|
||||
extern uint8_t can_irq_number[CAN_IRQS_ARRAY_SIZE][CAN_IRQS_ARRAY_SIZE];
|
||||
|
||||
bool can_set_speed(uint8_t can_number);
|
||||
void can_clear_send(CAN_TypeDef *CANx, uint8_t can_number);
|
||||
void update_can_health_pkt(uint8_t can_number, uint32_t ir_reg);
|
||||
|
||||
// ***************************** CAN *****************************
|
||||
// CANx_TX IRQ Handler
|
||||
void process_can(uint8_t can_number);
|
||||
// CANx_RX0 IRQ Handler
|
||||
// blink blue when we are receiving CAN messages
|
||||
void can_rx(uint8_t can_number);
|
||||
bool can_init(uint8_t can_number);
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "can_common_declarations.h"
|
||||
#include "board/drivers/drivers.h"
|
||||
|
||||
uint32_t safety_tx_blocked = 0;
|
||||
uint32_t safety_rx_invalid = 0;
|
||||
@@ -11,7 +11,6 @@ can_health_t can_health[PANDA_CAN_CNT] = {{0}, {0}, {0}};
|
||||
bool ignition_can = false;
|
||||
uint32_t ignition_can_cnt = 0U;
|
||||
|
||||
int pending_can_live = 0;
|
||||
bool can_silent = true;
|
||||
bool can_loopback = false;
|
||||
|
||||
@@ -29,7 +28,7 @@ bool can_loopback = false;
|
||||
__attribute__((section(".axisram"))) can_buffer(rx_q, CAN_RX_BUFFER_SIZE)
|
||||
__attribute__((section(".itcmram"))) can_buffer(tx1_q, CAN_TX_BUFFER_SIZE)
|
||||
__attribute__((section(".itcmram"))) can_buffer(tx2_q, CAN_TX_BUFFER_SIZE)
|
||||
#else
|
||||
#else // kept for PC
|
||||
can_buffer(rx_q, CAN_RX_BUFFER_SIZE)
|
||||
can_buffer(tx1_q, CAN_TX_BUFFER_SIZE)
|
||||
can_buffer(tx2_q, CAN_TX_BUFFER_SIZE)
|
||||
@@ -133,15 +132,11 @@ bus_config_t bus_config[PANDA_CAN_CNT] = {
|
||||
{ .bus_lookup = 0U, .can_num_lookup = 0U, .forwarding_bus = -1, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_auto = false, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false },
|
||||
{ .bus_lookup = 1U, .can_num_lookup = 1U, .forwarding_bus = -1, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_auto = false, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false },
|
||||
{ .bus_lookup = 2U, .can_num_lookup = 2U, .forwarding_bus = -1, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_auto = false, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false },
|
||||
// { .bus_lookup = 0xFFU, .can_num_lookup = 0xFFU, .forwarding_bus = -1, .can_speed = 333U, .can_data_speed = 333U, .canfd_auto = false, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false },
|
||||
};
|
||||
|
||||
void can_init_all(void) {
|
||||
for (uint8_t i=0U; i < PANDA_CAN_CNT; i++) {
|
||||
if (!current_board->has_canfd) {
|
||||
bus_config[i].can_data_speed = 0U;
|
||||
bus_config[i].canfd_enabled = false;
|
||||
}
|
||||
bus_config[i].canfd_enabled = false;
|
||||
can_clear(can_queues[i]);
|
||||
(void)can_init(i);
|
||||
}
|
||||
@@ -205,8 +200,14 @@ void ignition_can_hook(CANPacket_t *msg) {
|
||||
ignition_can = (msg->data[0] >> 5) == 0x6U;
|
||||
ignition_can_cnt = 0U;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TODO: this is too loose, Teslas have 0x222
|
||||
// body v2 exception
|
||||
// if (((msg->bus == 0U) || (msg->bus == 2U)) && (msg->addr == 0x222U)) {
|
||||
// ignition_can = true;
|
||||
// ignition_can_cnt = 0U;
|
||||
// }
|
||||
}
|
||||
|
||||
bool can_tx_check_min_slots_free(uint32_t min) {
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct {
|
||||
volatile uint32_t w_ptr;
|
||||
volatile uint32_t r_ptr;
|
||||
uint32_t fifo_size;
|
||||
CANPacket_t *elems;
|
||||
} can_ring;
|
||||
|
||||
typedef struct {
|
||||
uint8_t bus_lookup;
|
||||
uint8_t can_num_lookup;
|
||||
int8_t forwarding_bus;
|
||||
uint32_t can_speed;
|
||||
uint32_t can_data_speed;
|
||||
bool canfd_auto;
|
||||
bool canfd_enabled;
|
||||
bool brs_enabled;
|
||||
bool canfd_non_iso;
|
||||
} bus_config_t;
|
||||
|
||||
extern uint32_t safety_tx_blocked;
|
||||
extern uint32_t safety_rx_invalid;
|
||||
extern uint32_t tx_buffer_overflow;
|
||||
extern uint32_t rx_buffer_overflow;
|
||||
|
||||
extern can_health_t can_health[PANDA_CAN_CNT];
|
||||
|
||||
// Ignition detected from CAN meessages
|
||||
extern bool ignition_can;
|
||||
extern uint32_t ignition_can_cnt;
|
||||
|
||||
extern bool can_silent;
|
||||
|
||||
extern int pending_can_live;
|
||||
|
||||
// ******************* functions prototypes *********************
|
||||
bool can_init(uint8_t can_number);
|
||||
void process_can(uint8_t can_number);
|
||||
|
||||
// ********************* instantiate queues *********************
|
||||
extern can_ring *can_queues[PANDA_CAN_CNT];
|
||||
|
||||
// helpers
|
||||
#define WORD_TO_BYTE_ARRAY(dst8, src32) 0[dst8] = ((src32) & 0xFFU); 1[dst8] = (((src32) >> 8U) & 0xFFU); 2[dst8] = (((src32) >> 16U) & 0xFFU); 3[dst8] = (((src32) >> 24U) & 0xFFU)
|
||||
#define BYTE_ARRAY_TO_WORD(dst32, src8) ((dst32) = 0[src8] | (1[src8] << 8U) | (2[src8] << 16U) | (3[src8] << 24U))
|
||||
|
||||
// ********************* interrupt safe queue *********************
|
||||
bool can_pop(can_ring *q, CANPacket_t *elem);
|
||||
bool can_push(can_ring *q, const CANPacket_t *elem);
|
||||
uint32_t can_slots_empty(const can_ring *q);
|
||||
|
||||
// assign CAN numbering
|
||||
// bus num: CAN Bus numbers in panda, sent to/from USB
|
||||
// Min: 0; Max: 127; Bit 7 marks message as receipt (bus 129 is receipt for but 1)
|
||||
// cans: Look up MCU can interface from bus number
|
||||
// can number: numeric lookup for MCU CAN interfaces (0 = CAN1, 1 = CAN2, etc);
|
||||
// bus_lookup: Translates from 'can number' to 'bus number'.
|
||||
// can_num_lookup: Translates from 'bus number' to 'can number'.
|
||||
// forwarding bus: If >= 0, forward all messages from this bus to the specified bus.
|
||||
|
||||
// Helpers
|
||||
// Panda: Bus 0=CAN1 Bus 1=CAN2 Bus 2=CAN3
|
||||
extern bus_config_t bus_config[PANDA_CAN_CNT];
|
||||
|
||||
#define CANIF_FROM_CAN_NUM(num) (cans[num])
|
||||
#define BUS_NUM_FROM_CAN_NUM(num) (bus_config[num].bus_lookup)
|
||||
#define CAN_NUM_FROM_BUS_NUM(num) (bus_config[num].can_num_lookup)
|
||||
|
||||
void can_init_all(void);
|
||||
void can_set_orientation(bool flipped);
|
||||
#ifdef PANDA_JUNGLE
|
||||
void can_set_forwarding(uint8_t from, uint8_t to);
|
||||
#endif
|
||||
void ignition_can_hook(CANPacket_t *to_push);
|
||||
bool can_tx_check_min_slots_free(uint32_t min);
|
||||
uint8_t calculate_checksum(const uint8_t *dat, uint32_t len);
|
||||
void can_set_checksum(CANPacket_t *packet);
|
||||
bool can_check_checksum(CANPacket_t *packet);
|
||||
void can_send(CANPacket_t *to_push, uint8_t bus_number, bool skip_tx_hook);
|
||||
bool is_speed_valid(uint32_t speed, const uint32_t *all_speeds, uint8_t len);
|
||||
@@ -1,12 +1,16 @@
|
||||
#include "clock_source_declarations.h"
|
||||
#include "board/drivers/drivers.h"
|
||||
|
||||
#define CLOCK_SOURCE_PERIOD_MS 50U
|
||||
#define CLOCK_SOURCE_PULSE_LEN_MS 2U
|
||||
|
||||
void clock_source_set_timer_params(uint16_t param1, uint16_t param2) {
|
||||
// Pulse length of each channel
|
||||
register_set(&(TIM1->CCR1), (((param1 & 0xFF00U) >> 8U)*10U), 0xFFFFU);
|
||||
register_set(&(TIM1->CCR2), ((param1 & 0x00FFU)*10U), 0xFFFFU);
|
||||
register_set(&(TIM1->CCR3), (((param2 & 0xFF00U) >> 8U)*10U), 0xFFFFU);
|
||||
register_set(&(TIM8->CCR3), (((param2 & 0xFF00U) >> 8U)*10U), 0xFFFFU);
|
||||
// Timer period
|
||||
register_set(&(TIM1->ARR), (((param2 & 0x00FFU)*10U) - 1U), 0xFFFFU);
|
||||
register_set(&(TIM1->CCR4), ((TIM1->ARR + 1U) / 2U), 0xFFFFU);
|
||||
}
|
||||
|
||||
void clock_source_init(bool enable_channel1) {
|
||||
@@ -14,12 +18,12 @@ void clock_source_init(bool enable_channel1) {
|
||||
register_set(&(TIM1->PSC), ((APB2_TIMER_FREQ*100U)-1U), 0xFFFFU); // Tick on 0.1 ms
|
||||
register_set(&(TIM1->ARR), ((CLOCK_SOURCE_PERIOD_MS*10U) - 1U), 0xFFFFU); // Period
|
||||
register_set(&(TIM1->CCMR1), 0U, 0xFFFFU); // No output on compare
|
||||
register_set(&(TIM1->CCER), TIM_CCER_CC1E, 0xFFFFU); // Enable compare 1
|
||||
register_set(&(TIM1->CCER), TIM_CCER_CC1E | TIM_CCER_CC2NE, 0xFFFFU); // Enable compares
|
||||
register_set(&(TIM1->CCR1), (CLOCK_SOURCE_PULSE_LEN_MS*10U), 0xFFFFU); // Compare 1 value
|
||||
register_set(&(TIM1->CCR2), (CLOCK_SOURCE_PULSE_LEN_MS*10U), 0xFFFFU); // Compare 1 value
|
||||
register_set(&(TIM1->CCR3), (CLOCK_SOURCE_PULSE_LEN_MS*10U), 0xFFFFU); // Compare 1 value
|
||||
register_set(&(TIM1->CCR2), (CLOCK_SOURCE_PULSE_LEN_MS*10U), 0xFFFFU); // Compare 2 value
|
||||
register_set(&(TIM1->CCR4), (CLOCK_SOURCE_PERIOD_MS*5U), 0xFFFFU); // For slave timer
|
||||
register_set_bits(&(TIM1->DIER), TIM_DIER_UIE | TIM_DIER_CC1IE); // Enable interrupts
|
||||
register_set(&(TIM1->CR1), TIM_CR1_CEN, 0x3FU); // Enable timer
|
||||
|
||||
|
||||
// No interrupts
|
||||
NVIC_DisableIRQ(TIM1_UP_TIM10_IRQn);
|
||||
@@ -30,15 +34,33 @@ void clock_source_init(bool enable_channel1) {
|
||||
set_gpio_alternate(GPIOA, 8, GPIO_AF1_TIM1);
|
||||
}
|
||||
set_gpio_alternate(GPIOB, 14, GPIO_AF1_TIM1);
|
||||
set_gpio_alternate(GPIOB, 15, GPIO_AF1_TIM1);
|
||||
|
||||
// Set PWM mode
|
||||
register_set(&(TIM1->CCMR1), (0b110UL << TIM_CCMR1_OC1M_Pos) | (0b110UL << TIM_CCMR1_OC2M_Pos), 0xFFFFU);
|
||||
register_set(&(TIM1->CCMR2), (0b110UL << TIM_CCMR2_OC3M_Pos), 0xFFFFU);
|
||||
register_set(&(TIM1->CCMR2), (0b110UL << TIM_CCMR2_OC3M_Pos) | (0b111UL << TIM_CCMR2_OC4M_Pos), 0xFFFFU);
|
||||
|
||||
// Enable output
|
||||
register_set(&(TIM1->BDTR), TIM_BDTR_MOE, 0xFFFFU);
|
||||
|
||||
// Enable complementary compares
|
||||
register_set_bits(&(TIM1->CCER), TIM_CCER_CC2NE | TIM_CCER_CC3NE);
|
||||
// Sync with slave
|
||||
register_set(&(TIM1->SMCR), TIM_SMCR_MSM , 0xFFFFU);
|
||||
register_set(&(TIM1->CR2), (0b0111U << TIM_CR2_MMS_Pos), 0xFFFFU);
|
||||
register_set(&(TIM8->SMCR), (0b0100U << TIM_SMCR_SMS_Pos) | (0b000U << TIM_SMCR_TS_Pos), 0xFFFFU);
|
||||
|
||||
// Setup slave timer (TIM8)
|
||||
register_set(&(TIM8->PSC), TIM1->PSC, 0xFFFFU);
|
||||
register_set(&(TIM8->ARR), TIM1->ARR, 0xFFFFU);
|
||||
register_set(&(TIM8->CCMR2), (0b110UL << TIM_CCMR2_OC3M_Pos), 0xFFFFU);
|
||||
register_set(&(TIM8->CCR3), (CLOCK_SOURCE_PULSE_LEN_MS * 10U), 0xFFFFU);
|
||||
register_set(&(TIM8->CCER), TIM_CCER_CC3NE, 0xFFFFU);
|
||||
|
||||
// MOE for TIM8 as well
|
||||
register_set(&(TIM8->BDTR), TIM_BDTR_MOE, 0xFFFFU);
|
||||
|
||||
// Set GPIO
|
||||
set_gpio_alternate(GPIOB, 15, GPIO_AF3_TIM8);
|
||||
|
||||
// Enable timers
|
||||
register_set(&(TIM1->CR1), TIM_CR1_CEN, 0x3FU);
|
||||
register_set(&(TIM8->CR1), TIM_CR1_CEN, 0x3FU);
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define CLOCK_SOURCE_PERIOD_MS 50U
|
||||
#define CLOCK_SOURCE_PULSE_LEN_MS 2U
|
||||
|
||||
void clock_source_set_timer_params(uint16_t param1, uint16_t param2);
|
||||
void clock_source_init(bool enable_channel1);
|
||||
@@ -0,0 +1,287 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/can.h"
|
||||
#include "board/health.h"
|
||||
#include "board/crc.h"
|
||||
#ifdef STM32H7
|
||||
#include "board/stm32h7/lladc_declarations.h"
|
||||
#endif
|
||||
|
||||
// ******************** bootkick ********************
|
||||
|
||||
extern bool bootkick_reset_triggered;
|
||||
|
||||
void bootkick_tick(bool ignition, bool recent_heartbeat);
|
||||
|
||||
// ******************** can_common ********************
|
||||
|
||||
typedef struct {
|
||||
volatile uint32_t w_ptr;
|
||||
volatile uint32_t r_ptr;
|
||||
uint32_t fifo_size;
|
||||
CANPacket_t *elems;
|
||||
} can_ring;
|
||||
|
||||
typedef struct {
|
||||
uint8_t bus_lookup;
|
||||
uint8_t can_num_lookup;
|
||||
int8_t forwarding_bus;
|
||||
uint32_t can_speed;
|
||||
uint32_t can_data_speed;
|
||||
bool canfd_auto;
|
||||
bool canfd_enabled;
|
||||
bool brs_enabled;
|
||||
bool canfd_non_iso;
|
||||
} bus_config_t;
|
||||
|
||||
extern uint32_t safety_tx_blocked;
|
||||
extern uint32_t safety_rx_invalid;
|
||||
extern uint32_t tx_buffer_overflow;
|
||||
extern uint32_t rx_buffer_overflow;
|
||||
|
||||
extern can_health_t can_health[PANDA_CAN_CNT];
|
||||
|
||||
// Ignition detected from CAN meessages
|
||||
extern bool ignition_can;
|
||||
extern uint32_t ignition_can_cnt;
|
||||
|
||||
extern bool can_silent;
|
||||
extern bool can_loopback;
|
||||
|
||||
// ******************* functions prototypes *********************
|
||||
bool can_init(uint8_t can_number);
|
||||
void process_can(uint8_t can_number);
|
||||
|
||||
// ********************* instantiate queues *********************
|
||||
extern can_ring *can_queues[PANDA_CAN_CNT];
|
||||
|
||||
// helpers
|
||||
#define WORD_TO_BYTE_ARRAY(dst8, src32) 0[dst8] = ((src32) & 0xFFU); 1[dst8] = (((src32) >> 8U) & 0xFFU); 2[dst8] = (((src32) >> 16U) & 0xFFU); 3[dst8] = (((src32) >> 24U) & 0xFFU)
|
||||
#define BYTE_ARRAY_TO_WORD(dst32, src8) ((dst32) = 0[src8] | (1[src8] << 8U) | (2[src8] << 16U) | (3[src8] << 24U))
|
||||
|
||||
// ********************* interrupt safe queue *********************
|
||||
bool can_pop(can_ring *q, CANPacket_t *elem);
|
||||
bool can_push(can_ring *q, const CANPacket_t *elem);
|
||||
uint32_t can_slots_empty(const can_ring *q);
|
||||
extern bus_config_t bus_config[PANDA_CAN_CNT];
|
||||
|
||||
#define CANIF_FROM_CAN_NUM(num) (cans[num])
|
||||
#define BUS_NUM_FROM_CAN_NUM(num) (bus_config[num].bus_lookup)
|
||||
#define CAN_NUM_FROM_BUS_NUM(num) (bus_config[num].can_num_lookup)
|
||||
|
||||
void can_init_all(void);
|
||||
void can_set_orientation(bool flipped);
|
||||
#ifdef PANDA_JUNGLE
|
||||
void can_set_forwarding(uint8_t from, uint8_t to);
|
||||
#endif
|
||||
void ignition_can_hook(CANPacket_t *to_push);
|
||||
bool can_tx_check_min_slots_free(uint32_t min);
|
||||
uint8_t calculate_checksum(const uint8_t *dat, uint32_t len);
|
||||
void can_set_checksum(CANPacket_t *packet);
|
||||
bool can_check_checksum(CANPacket_t *packet);
|
||||
void can_send(CANPacket_t *to_push, uint8_t bus_number, bool skip_tx_hook);
|
||||
bool is_speed_valid(uint32_t speed, const uint32_t *all_speeds, uint8_t len);
|
||||
|
||||
// ******************** clock_source ********************
|
||||
|
||||
void clock_source_set_timer_params(uint16_t param1, uint16_t param2);
|
||||
void clock_source_init(bool enable_channel1);
|
||||
|
||||
// ******************** fan ********************
|
||||
|
||||
struct fan_state_t {
|
||||
uint16_t tach_counter;
|
||||
uint16_t rpm;
|
||||
uint8_t power;
|
||||
float error_integral;
|
||||
uint8_t cooldown_counter;
|
||||
};
|
||||
extern struct fan_state_t fan_state;
|
||||
|
||||
void fan_set_power(uint8_t percentage);
|
||||
void llfan_init(void);
|
||||
void fan_init(void);
|
||||
// Call this at FAN_TICK_FREQ
|
||||
void fan_tick(void);
|
||||
|
||||
// ******************** fdcan ********************
|
||||
#ifdef STM32H7
|
||||
|
||||
typedef struct {
|
||||
volatile uint32_t header[2];
|
||||
volatile uint32_t data_word[CANPACKET_DATA_SIZE_MAX/4U];
|
||||
} canfd_fifo;
|
||||
|
||||
extern FDCAN_GlobalTypeDef *cans[PANDA_CAN_CNT];
|
||||
|
||||
#define CAN_ACK_ERROR 3U
|
||||
|
||||
void can_clear_send(FDCAN_GlobalTypeDef *FDCANx, uint8_t can_number);
|
||||
void update_can_health_pkt(uint8_t can_number, uint32_t ir_reg);
|
||||
|
||||
void process_can(uint8_t can_number);
|
||||
void can_rx(uint8_t can_number);
|
||||
bool can_init(uint8_t can_number);
|
||||
|
||||
// ******************** harness ********************
|
||||
|
||||
#define HARNESS_STATUS_NC 0U
|
||||
#define HARNESS_STATUS_NORMAL 1U
|
||||
#define HARNESS_STATUS_FLIPPED 2U
|
||||
|
||||
struct harness_t {
|
||||
uint8_t status;
|
||||
uint16_t sbu1_voltage_mV;
|
||||
uint16_t sbu2_voltage_mV;
|
||||
bool relay_driven;
|
||||
bool sbu_adc_lock;
|
||||
};
|
||||
extern struct harness_t harness;
|
||||
|
||||
struct harness_configuration {
|
||||
GPIO_TypeDef * const GPIO_SBU1;
|
||||
GPIO_TypeDef * const GPIO_SBU2;
|
||||
GPIO_TypeDef * const GPIO_relay_SBU1;
|
||||
GPIO_TypeDef * const GPIO_relay_SBU2;
|
||||
const uint8_t pin_SBU1;
|
||||
const uint8_t pin_SBU2;
|
||||
const uint8_t pin_relay_SBU1;
|
||||
const uint8_t pin_relay_SBU2;
|
||||
const adc_signal_t adc_signal_SBU1;
|
||||
const adc_signal_t adc_signal_SBU2;
|
||||
};
|
||||
|
||||
// The ignition relay is only used for testing purposes
|
||||
void set_intercept_relay(bool intercept, bool ignition_relay);
|
||||
bool harness_check_ignition(void);
|
||||
void harness_tick(void);
|
||||
void harness_init(void);
|
||||
|
||||
// ******************** interrupts ********************
|
||||
|
||||
typedef struct interrupt {
|
||||
IRQn_Type irq_type;
|
||||
void (*handler)(void);
|
||||
uint32_t call_counter;
|
||||
uint32_t call_rate;
|
||||
uint32_t max_call_rate; // Call rate is defined as the amount of calls each second
|
||||
uint32_t call_rate_fault;
|
||||
} interrupt;
|
||||
|
||||
void interrupt_timer_init(void);
|
||||
uint32_t microsecond_timer_get(void);
|
||||
void unused_interrupt_handler(void);
|
||||
|
||||
extern interrupt interrupts[NUM_INTERRUPTS];
|
||||
|
||||
#define REGISTER_INTERRUPT(irq_num, func_ptr, call_rate_max, rate_fault) \
|
||||
interrupts[irq_num].irq_type = (irq_num); \
|
||||
interrupts[irq_num].handler = (func_ptr); \
|
||||
interrupts[irq_num].call_counter = 0U; \
|
||||
interrupts[irq_num].call_rate = 0U; \
|
||||
interrupts[irq_num].max_call_rate = (call_rate_max); \
|
||||
interrupts[irq_num].call_rate_fault = (rate_fault);
|
||||
|
||||
extern float interrupt_load;
|
||||
|
||||
void handle_interrupt(IRQn_Type irq_type);
|
||||
// Every second
|
||||
void interrupt_timer_handler(void);
|
||||
void init_interrupts(bool check_rate_limit);
|
||||
|
||||
#endif // STM32H7
|
||||
|
||||
// ******************** registers ********************
|
||||
|
||||
// 10 bit hash with 23 as a prime
|
||||
#define REGISTER_MAP_SIZE 0x3FFU
|
||||
#define HASHING_PRIME 23U
|
||||
|
||||
// Do not put bits in the check mask that get changed by the hardware
|
||||
void register_set(volatile uint32_t *addr, uint32_t val, uint32_t mask);
|
||||
// Set individual bits. Also add them to the check_mask.
|
||||
// Do not use this to change bits that get reset by the hardware
|
||||
void register_set_bits(volatile uint32_t *addr, uint32_t val);
|
||||
// Clear individual bits. Also add them to the check_mask.
|
||||
// Do not use this to clear bits that get set by the hardware
|
||||
void register_clear_bits(volatile uint32_t *addr, uint32_t val);
|
||||
// To be called periodically
|
||||
void check_registers(void);
|
||||
void init_registers(void);
|
||||
|
||||
// ******************** simple_watchdog ********************
|
||||
|
||||
typedef struct simple_watchdog_state_t {
|
||||
uint32_t fault;
|
||||
uint32_t last_ts;
|
||||
uint32_t threshold;
|
||||
} simple_watchdog_state_t;
|
||||
|
||||
void simple_watchdog_kick(void);
|
||||
void simple_watchdog_init(uint32_t fault, uint32_t threshold);
|
||||
|
||||
// ******************** spi ********************
|
||||
|
||||
// got max rate from hitting a non-existent endpoint
|
||||
// in a tight loop, plus some buffer
|
||||
#define SPI_IRQ_RATE 16000U
|
||||
|
||||
#define SPI_BUF_SIZE 4096U
|
||||
extern uint8_t spi_buf_rx[SPI_BUF_SIZE];
|
||||
extern uint8_t spi_buf_tx[SPI_BUF_SIZE];
|
||||
|
||||
extern uint16_t spi_error_count;
|
||||
|
||||
void can_tx_comms_resume_spi(void);
|
||||
void spi_init(void);
|
||||
void spi_rx_done(void);
|
||||
void spi_tx_done(bool reset);
|
||||
|
||||
// ******************** uart ********************
|
||||
#ifdef STM32H7
|
||||
|
||||
// ***************************** Definitions *****************************
|
||||
#define FIFO_SIZE_INT 0x400U
|
||||
|
||||
typedef struct uart_ring {
|
||||
volatile uint16_t w_ptr_tx;
|
||||
volatile uint16_t r_ptr_tx;
|
||||
uint8_t *elems_tx;
|
||||
uint32_t tx_fifo_size;
|
||||
volatile uint16_t w_ptr_rx;
|
||||
volatile uint16_t r_ptr_rx;
|
||||
uint8_t *elems_rx;
|
||||
uint32_t rx_fifo_size;
|
||||
USART_TypeDef *uart;
|
||||
void (*callback)(struct uart_ring*);
|
||||
bool overwrite;
|
||||
} uart_ring;
|
||||
|
||||
// ***************************** Function prototypes *****************************
|
||||
void debug_ring_callback(uart_ring *ring);
|
||||
void uart_tx_ring(uart_ring *q);
|
||||
uart_ring *get_ring_by_number(int a);
|
||||
// ************************* Low-level buffer functions *************************
|
||||
bool get_char(uart_ring *q, char *elem);
|
||||
bool injectc(uart_ring *q, char elem);
|
||||
bool put_char(uart_ring *q, char elem);
|
||||
void clear_uart_buff(uart_ring *q);
|
||||
// ************************ High-level debug functions **********************
|
||||
void putch(const char a);
|
||||
void print(const char *a);
|
||||
void puthx(uint32_t i, uint8_t len);
|
||||
void puth(unsigned int i);
|
||||
#if defined(DEBUG_SPI) || defined(BOOTSTUB) || defined(DEBUG)
|
||||
static void puth4(unsigned int i);
|
||||
#endif
|
||||
#if defined(DEBUG_SPI) || defined(DEBUG_USB) || defined(DEBUG_COMMS)
|
||||
static void hexdump(const void *a, int l);
|
||||
#endif
|
||||
|
||||
#endif // STM32H7
|
||||
|
||||
// ******************** usb ********************
|
||||
|
||||
void usb_init(void);
|
||||
void refresh_can_tx_slots_available(void);
|
||||
void can_tx_comms_resume_usb(void);
|
||||
@@ -1,8 +1,37 @@
|
||||
#include "stm32h7/lli2c.h"
|
||||
#include "board/stm32h7/lli2c.h"
|
||||
|
||||
#define CODEC_I2C_ADDR 0x10
|
||||
|
||||
void fake_siren_init(void);
|
||||
void siren_tim7_init(void) {
|
||||
// Init trigger timer (around 2.5kHz)
|
||||
register_set(&TIM7->PSC, 0U, 0xFFFFU);
|
||||
register_set(&TIM7->ARR, 133U, 0xFFFFU);
|
||||
register_set(&TIM7->CR2, (0b10U << TIM_CR2_MMS_Pos), TIM_CR2_MMS_Msk);
|
||||
register_set(&TIM7->CR1, TIM_CR1_ARPE | TIM_CR1_URS, 0x088EU);
|
||||
TIM7->SR = 0U;
|
||||
TIM7->CR1 |= TIM_CR1_CEN;
|
||||
}
|
||||
|
||||
void siren_dac_init(void) {
|
||||
DAC1->DHR8R1 = (1U << 7);
|
||||
DAC1->DHR8R2 = (1U << 7);
|
||||
register_set(&DAC1->MCR, 0U, 0xFFFFFFFFU);
|
||||
register_set(&DAC1->CR, DAC_CR_TEN1 | (6U << DAC_CR_TSEL1_Pos) | DAC_CR_DMAEN1, 0xFFFFFFFFU);
|
||||
register_set_bits(&DAC1->CR, DAC_CR_EN1 | DAC_CR_EN2);
|
||||
}
|
||||
|
||||
void siren_dma_init(void) {
|
||||
// 1Vpp sine wave with 1V offset
|
||||
static const uint8_t fake_siren_lut[360] = { 134U, 135U, 137U, 138U, 139U, 140U, 141U, 143U, 144U, 145U, 146U, 148U, 149U, 150U, 151U, 152U, 154U, 155U, 156U, 157U, 158U, 159U, 160U, 162U, 163U, 164U, 165U, 166U, 167U, 168U, 169U, 170U, 171U, 172U, 174U, 175U, 176U, 177U, 177U, 178U, 179U, 180U, 181U, 182U, 183U, 184U, 185U, 186U, 186U, 187U, 188U, 189U, 190U, 190U, 191U, 192U, 193U, 193U, 194U, 195U, 195U, 196U, 196U, 197U, 197U, 198U, 199U, 199U, 199U, 200U, 200U, 201U, 201U, 202U, 202U, 202U, 203U, 203U, 203U, 203U, 204U, 204U, 204U, 204U, 204U, 204U, 204U, 205U, 205U, 205U, 205U, 205U, 205U, 205U, 204U, 204U, 204U, 204U, 204U, 204U, 204U, 203U, 203U, 203U, 203U, 202U, 202U, 202U, 201U, 201U, 200U, 200U, 199U, 199U, 199U, 198U, 197U, 197U, 196U, 196U, 195U, 195U, 194U, 193U, 193U, 192U, 191U, 190U, 190U, 189U, 188U, 187U, 186U, 186U, 185U, 184U, 183U, 182U, 181U, 180U, 179U, 178U, 177U, 177U, 176U, 175U, 174U, 172U, 171U, 170U, 169U, 168U, 167U, 166U, 165U, 164U, 163U, 162U, 160U, 159U, 158U, 157U, 156U, 155U, 154U, 152U, 151U, 150U, 149U, 148U, 146U, 145U, 144U, 143U, 141U, 140U, 139U, 138U, 137U, 135U, 134U, 133U, 132U, 130U, 129U, 128U, 127U, 125U, 124U, 123U, 122U, 121U, 119U, 118U, 117U, 116U, 115U, 113U, 112U, 111U, 110U, 109U, 108U, 106U, 105U, 104U, 103U, 102U, 101U, 100U, 99U, 98U, 97U, 96U, 95U, 94U, 93U, 92U, 91U, 90U, 89U, 88U, 87U, 86U, 85U, 84U, 83U, 82U, 82U, 81U, 80U, 79U, 78U, 78U, 77U, 76U, 76U, 75U, 74U, 74U, 73U, 72U, 72U, 71U, 71U, 70U, 70U, 69U, 69U, 68U, 68U, 67U, 67U, 67U, 66U, 66U, 66U, 65U, 65U, 65U, 65U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 63U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 65U, 65U, 65U, 65U, 66U, 66U, 66U, 67U, 67U, 67U, 68U, 68U, 69U, 69U, 70U, 70U, 71U, 71U, 72U, 72U, 73U, 74U, 74U, 75U, 76U, 76U, 77U, 78U, 78U, 79U, 80U, 81U, 82U, 82U, 83U, 84U, 85U, 86U, 87U, 88U, 89U, 90U, 91U, 92U, 93U, 94U, 95U, 96U, 97U, 98U, 99U, 100U, 101U, 102U, 103U, 104U, 105U, 106U, 108U, 109U, 110U, 111U, 112U, 113U, 115U, 116U, 117U, 118U, 119U, 121U, 122U, 123U, 124U, 125U, 127U, 128U, 129U, 130U, 132U, 133U };
|
||||
// Setup DMAMUX (DAC_CH1_DMA as input)
|
||||
register_set(&DMAMUX1_Channel1->CCR, 67U, DMAMUX_CxCR_DMAREQ_ID_Msk);
|
||||
register_set(&DMA1_Stream1->PAR, (uint32_t)&(DAC1->DHR8R1), 0xFFFFFFFFU);
|
||||
// Setup DMA
|
||||
register_set(&DMA1_Stream1->M0AR, (uint32_t)fake_siren_lut, 0xFFFFFFFFU);
|
||||
register_set(&DMA1_Stream1->FCR, 0U, 0x00000083U);
|
||||
DMA1_Stream1->NDTR = sizeof(fake_siren_lut);
|
||||
DMA1_Stream1->CR = (0b11UL << DMA_SxCR_PL_Pos) | DMA_SxCR_MINC | DMA_SxCR_CIRC | (1U << DMA_SxCR_DIR_Pos);
|
||||
}
|
||||
|
||||
void fake_siren_codec_enable(bool enabled) {
|
||||
if (enabled) {
|
||||
@@ -28,13 +57,21 @@ void fake_siren_codec_enable(bool enabled) {
|
||||
}
|
||||
}
|
||||
|
||||
static void fake_i2c_siren_init(void) {
|
||||
siren_dac_init();
|
||||
siren_dma_init();
|
||||
siren_tim7_init();
|
||||
// Enable the I2C to the codec
|
||||
i2c_init(I2C5);
|
||||
fake_siren_codec_enable(false);
|
||||
}
|
||||
|
||||
void fake_siren_set(bool enabled) {
|
||||
void fake_i2c_siren_set(bool enabled) {
|
||||
static bool initialized = false;
|
||||
static bool fake_siren_enabled = false;
|
||||
|
||||
if (!initialized) {
|
||||
fake_siren_init();
|
||||
fake_i2c_siren_init();
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
@@ -50,35 +87,29 @@ void fake_siren_set(bool enabled) {
|
||||
fake_siren_enabled = enabled;
|
||||
}
|
||||
|
||||
void fake_siren_init(void) {
|
||||
// 1Vpp sine wave with 1V offset
|
||||
static const uint8_t fake_siren_lut[360] = { 134U, 135U, 137U, 138U, 139U, 140U, 141U, 143U, 144U, 145U, 146U, 148U, 149U, 150U, 151U, 152U, 154U, 155U, 156U, 157U, 158U, 159U, 160U, 162U, 163U, 164U, 165U, 166U, 167U, 168U, 169U, 170U, 171U, 172U, 174U, 175U, 176U, 177U, 177U, 178U, 179U, 180U, 181U, 182U, 183U, 184U, 185U, 186U, 186U, 187U, 188U, 189U, 190U, 190U, 191U, 192U, 193U, 193U, 194U, 195U, 195U, 196U, 196U, 197U, 197U, 198U, 199U, 199U, 199U, 200U, 200U, 201U, 201U, 202U, 202U, 202U, 203U, 203U, 203U, 203U, 204U, 204U, 204U, 204U, 204U, 204U, 204U, 205U, 205U, 205U, 205U, 205U, 205U, 205U, 204U, 204U, 204U, 204U, 204U, 204U, 204U, 203U, 203U, 203U, 203U, 202U, 202U, 202U, 201U, 201U, 200U, 200U, 199U, 199U, 199U, 198U, 197U, 197U, 196U, 196U, 195U, 195U, 194U, 193U, 193U, 192U, 191U, 190U, 190U, 189U, 188U, 187U, 186U, 186U, 185U, 184U, 183U, 182U, 181U, 180U, 179U, 178U, 177U, 177U, 176U, 175U, 174U, 172U, 171U, 170U, 169U, 168U, 167U, 166U, 165U, 164U, 163U, 162U, 160U, 159U, 158U, 157U, 156U, 155U, 154U, 152U, 151U, 150U, 149U, 148U, 146U, 145U, 144U, 143U, 141U, 140U, 139U, 138U, 137U, 135U, 134U, 133U, 132U, 130U, 129U, 128U, 127U, 125U, 124U, 123U, 122U, 121U, 119U, 118U, 117U, 116U, 115U, 113U, 112U, 111U, 110U, 109U, 108U, 106U, 105U, 104U, 103U, 102U, 101U, 100U, 99U, 98U, 97U, 96U, 95U, 94U, 93U, 92U, 91U, 90U, 89U, 88U, 87U, 86U, 85U, 84U, 83U, 82U, 82U, 81U, 80U, 79U, 78U, 78U, 77U, 76U, 76U, 75U, 74U, 74U, 73U, 72U, 72U, 71U, 71U, 70U, 70U, 69U, 69U, 68U, 68U, 67U, 67U, 67U, 66U, 66U, 66U, 65U, 65U, 65U, 65U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 63U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 65U, 65U, 65U, 65U, 66U, 66U, 66U, 67U, 67U, 67U, 68U, 68U, 69U, 69U, 70U, 70U, 71U, 71U, 72U, 72U, 73U, 74U, 74U, 75U, 76U, 76U, 77U, 78U, 78U, 79U, 80U, 81U, 82U, 82U, 83U, 84U, 85U, 86U, 87U, 88U, 89U, 90U, 91U, 92U, 93U, 94U, 95U, 96U, 97U, 98U, 99U, 100U, 101U, 102U, 103U, 104U, 105U, 106U, 108U, 109U, 110U, 111U, 112U, 113U, 115U, 116U, 117U, 118U, 119U, 121U, 122U, 123U, 124U, 125U, 127U, 128U, 129U, 130U, 132U, 133U };
|
||||
void fake_siren_set(bool enabled) {
|
||||
static bool initialized = false;
|
||||
static bool fake_siren_enabled = false;
|
||||
|
||||
// Init DAC
|
||||
register_set(&DAC1->MCR, 0U, 0xFFFFFFFFU);
|
||||
register_set(&DAC1->CR, DAC_CR_TEN1 | (6U << DAC_CR_TSEL1_Pos) | DAC_CR_DMAEN1, 0xFFFFFFFFU);
|
||||
register_set_bits(&DAC1->CR, DAC_CR_EN1);
|
||||
if (!initialized) {
|
||||
siren_tim7_init();
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
// Setup DMAMUX (DAC_CH1_DMA as input)
|
||||
register_set(&DMAMUX1_Channel1->CCR, 67U, DMAMUX_CxCR_DMAREQ_ID_Msk);
|
||||
|
||||
// Setup DMA
|
||||
register_set(&DMA1_Stream1->M0AR, (uint32_t) fake_siren_lut, 0xFFFFFFFFU);
|
||||
register_set(&DMA1_Stream1->PAR, (uint32_t) &(DAC1->DHR8R1), 0xFFFFFFFFU);
|
||||
DMA1_Stream1->NDTR = sizeof(fake_siren_lut);
|
||||
register_set(&DMA1_Stream1->FCR, 0U, 0x00000083U);
|
||||
DMA1_Stream1->CR = (0b11UL << DMA_SxCR_PL_Pos);
|
||||
DMA1_Stream1->CR |= DMA_SxCR_MINC | DMA_SxCR_CIRC | (1U << DMA_SxCR_DIR_Pos);
|
||||
|
||||
// Init trigger timer (around 2.5kHz)
|
||||
register_set(&TIM7->PSC, 0U, 0xFFFFU);
|
||||
register_set(&TIM7->ARR, 133U, 0xFFFFU);
|
||||
register_set(&TIM7->CR2, (0b10U << TIM_CR2_MMS_Pos), TIM_CR2_MMS_Msk);
|
||||
register_set(&TIM7->CR1, TIM_CR1_ARPE | TIM_CR1_URS, 0x088EU);
|
||||
TIM7->SR = 0U;
|
||||
TIM7->CR1 |= TIM_CR1_CEN;
|
||||
|
||||
// Enable the I2C to the codec
|
||||
i2c_init(I2C5);
|
||||
fake_siren_codec_enable(false);
|
||||
if (enabled != fake_siren_enabled) {
|
||||
if (enabled) {
|
||||
sound_stop_dac();
|
||||
siren_dac_init();
|
||||
siren_dma_init();
|
||||
current_board->set_amp_enabled(true);
|
||||
register_set_bits(&DMA1_Stream1->CR, DMA_SxCR_EN);
|
||||
} else {
|
||||
current_board->set_amp_enabled(false);
|
||||
// Stop modified 8-bit DAC and start normal 12-bit DAC
|
||||
sound_stop_dac();
|
||||
sound_init_dac();
|
||||
register_set_bits(&BDMA_Channel0->CCR, BDMA_CCR_EN);
|
||||
}
|
||||
fake_siren_enabled = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
+10
-49
@@ -1,68 +1,39 @@
|
||||
#include "fan_declarations.h"
|
||||
#include "board/drivers/drivers.h"
|
||||
|
||||
struct fan_state_t fan_state;
|
||||
|
||||
static const uint8_t FAN_TICK_FREQ = 8U;
|
||||
static const uint8_t FAN_STALL_THRESHOLD_MIN = 3U;
|
||||
|
||||
|
||||
void fan_set_power(uint8_t percentage) {
|
||||
fan_state.target_rpm = ((current_board->fan_max_rpm * CLAMP(percentage, 0U, 100U)) / 100U);
|
||||
if (percentage > 0U) {
|
||||
fan_state.power = CLAMP(percentage, 20U, 100U);
|
||||
} else {
|
||||
fan_state.power = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
void llfan_init(void);
|
||||
void fan_init(void) {
|
||||
fan_state.stall_threshold = FAN_STALL_THRESHOLD_MIN;
|
||||
fan_state.cooldown_counter = current_board->fan_enable_cooldown_time * FAN_TICK_FREQ;
|
||||
llfan_init();
|
||||
}
|
||||
|
||||
// Call this at FAN_TICK_FREQ
|
||||
void fan_tick(void) {
|
||||
const float FAN_I = 6.5f;
|
||||
const uint8_t FAN_STALL_THRESHOLD_MAX = 8U;
|
||||
|
||||
if (current_board->fan_max_rpm > 0U) {
|
||||
if (current_board->has_fan) {
|
||||
// Measure fan RPM
|
||||
uint16_t fan_rpm_fast = fan_state.tach_counter * (60U * FAN_TICK_FREQ / 4U); // 4 interrupts per rotation
|
||||
fan_state.tach_counter = 0U;
|
||||
fan_state.rpm = (fan_rpm_fast + (3U * fan_state.rpm)) / 4U;
|
||||
|
||||
// Stall detection
|
||||
bool fan_stalled = false;
|
||||
if (current_board->fan_stall_recovery) {
|
||||
if (fan_state.target_rpm > 0U) {
|
||||
if (fan_rpm_fast == 0U) {
|
||||
fan_state.stall_counter = MIN(fan_state.stall_counter + 1U, 254U);
|
||||
} else {
|
||||
fan_state.stall_counter = 0U;
|
||||
}
|
||||
|
||||
if (fan_state.stall_counter > (fan_state.stall_threshold*FAN_TICK_FREQ)) {
|
||||
fan_stalled = true;
|
||||
fan_state.stall_counter = 0U;
|
||||
fan_state.stall_threshold = CLAMP(fan_state.stall_threshold + 2U, FAN_STALL_THRESHOLD_MIN, FAN_STALL_THRESHOLD_MAX);
|
||||
fan_state.total_stall_count += 1U;
|
||||
|
||||
// datasheet gives this range as the minimum startup duty
|
||||
fan_state.error_integral = CLAMP(fan_state.error_integral, 20.0f, 45.0f);
|
||||
}
|
||||
} else {
|
||||
fan_state.stall_counter = 0U;
|
||||
fan_state.stall_threshold = FAN_STALL_THRESHOLD_MIN;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_FAN
|
||||
puth(fan_state.target_rpm);
|
||||
print(" "); puth(fan_rpm_fast);
|
||||
print(" "); puth(fan_state.power);
|
||||
print(" "); puth(fan_state.stall_counter);
|
||||
print("\n");
|
||||
#endif
|
||||
|
||||
// Cooldown counter
|
||||
if (fan_state.target_rpm > 0U) {
|
||||
// Cooldown counter to prevent noise on tachometer line.
|
||||
if (fan_state.power > 0U) {
|
||||
fan_state.cooldown_counter = current_board->fan_enable_cooldown_time * FAN_TICK_FREQ;
|
||||
} else {
|
||||
if (fan_state.cooldown_counter > 0U) {
|
||||
@@ -70,18 +41,8 @@ void fan_tick(void) {
|
||||
}
|
||||
}
|
||||
|
||||
// Update controller
|
||||
if (fan_state.target_rpm == 0U) {
|
||||
fan_state.error_integral = 0.0f;
|
||||
} else {
|
||||
float error = (fan_state.target_rpm - fan_rpm_fast) / ((float) current_board->fan_max_rpm);
|
||||
fan_state.error_integral += FAN_I * error;
|
||||
}
|
||||
fan_state.error_integral = CLAMP(fan_state.error_integral, 0U, current_board->fan_max_pwm);
|
||||
fan_state.power = fan_state.error_integral;
|
||||
|
||||
// Set PWM and enable line
|
||||
pwm_set(TIM3, 3, fan_state.power);
|
||||
current_board->set_fan_enabled(!fan_stalled && ((fan_state.target_rpm > 0U) || (fan_state.cooldown_counter > 0U)));
|
||||
current_board->set_fan_enabled((fan_state.power > 0U) || (fan_state.cooldown_counter > 0U));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
struct fan_state_t {
|
||||
uint16_t tach_counter;
|
||||
uint16_t rpm;
|
||||
uint16_t target_rpm;
|
||||
uint8_t power;
|
||||
float error_integral;
|
||||
uint8_t stall_counter;
|
||||
uint8_t stall_threshold;
|
||||
uint8_t total_stall_count;
|
||||
uint8_t cooldown_counter;
|
||||
};
|
||||
extern struct fan_state_t fan_state;
|
||||
|
||||
void fan_set_power(uint8_t percentage);
|
||||
void llfan_init(void);
|
||||
void fan_init(void);
|
||||
// Call this at FAN_TICK_FREQ
|
||||
void fan_tick(void);
|
||||
+10
-11
@@ -1,6 +1,6 @@
|
||||
#include "fdcan_declarations.h"
|
||||
#include "board/drivers/drivers.h"
|
||||
|
||||
FDCAN_GlobalTypeDef *cans[CANS_ARRAY_SIZE] = {FDCAN1, FDCAN2, FDCAN3};
|
||||
FDCAN_GlobalTypeDef *cans[PANDA_CAN_CNT] = {FDCAN1, FDCAN2, FDCAN3};
|
||||
|
||||
static bool can_set_speed(uint8_t can_number) {
|
||||
bool ret = true;
|
||||
@@ -13,7 +13,7 @@ static bool can_set_speed(uint8_t can_number) {
|
||||
bus_config[bus_number].can_data_speed,
|
||||
bus_config[bus_number].canfd_non_iso,
|
||||
can_loopback,
|
||||
(unsigned int)(can_silent) & (1U << can_number)
|
||||
can_silent
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
@@ -32,7 +32,7 @@ void can_clear_send(FDCAN_GlobalTypeDef *FDCANx, uint8_t can_number) {
|
||||
}
|
||||
|
||||
void update_can_health_pkt(uint8_t can_number, uint32_t ir_reg) {
|
||||
uint8_t can_irq_number[3][2] = {
|
||||
uint8_t can_irq_number[PANDA_CAN_CNT][2] = {
|
||||
{ FDCAN1_IT0_IRQn, FDCAN1_IT1_IRQn },
|
||||
{ FDCAN2_IT0_IRQn, FDCAN2_IT1_IRQn },
|
||||
{ FDCAN3_IT0_IRQn, FDCAN3_IT1_IRQn },
|
||||
@@ -63,7 +63,6 @@ void update_can_health_pkt(uint8_t can_number, uint32_t ir_reg) {
|
||||
can_health[can_number].irq0_call_rate = interrupts[can_irq_number[can_number][0]].call_rate;
|
||||
can_health[can_number].irq1_call_rate = interrupts[can_irq_number[can_number][1]].call_rate;
|
||||
|
||||
|
||||
if (ir_reg != 0U) {
|
||||
// Clear error interrupts
|
||||
FDCANx->IR |= (FDCAN_IR_PED | FDCAN_IR_PEA | FDCAN_IR_EP | FDCAN_IR_BO | FDCAN_IR_RF0L);
|
||||
@@ -158,17 +157,13 @@ void can_rx(uint8_t can_number) {
|
||||
|
||||
// Clear all new messages from Rx FIFO 0
|
||||
FDCANx->IR |= FDCAN_IR_RF0N;
|
||||
while((FDCANx->RXF0S & FDCAN_RXF0S_F0FL) != 0U) {
|
||||
while ((FDCANx->RXF0S & FDCAN_RXF0S_F0FL) != 0U) {
|
||||
can_health[can_number].total_rx_cnt += 1U;
|
||||
|
||||
// can is live
|
||||
pending_can_live = 1;
|
||||
|
||||
// get the index of the next RX FIFO element (0 to FDCAN_RX_FIFO_0_EL_CNT - 1)
|
||||
uint32_t rx_fifo_idx = (uint8_t)((FDCANx->RXF0S >> FDCAN_RXF0S_F0GI_Pos) & 0x3FU);
|
||||
|
||||
// Recommended to offset get index by at least +1 if RX FIFO is in overwrite mode and full (datasheet)
|
||||
if((FDCANx->RXF0S & FDCAN_RXF0S_F0F) == FDCAN_RXF0S_F0F) {
|
||||
if ((FDCANx->RXF0S & FDCAN_RXF0S_F0F) == FDCAN_RXF0S_F0F) {
|
||||
rx_fifo_idx = ((rx_fifo_idx + 1U) >= FDCAN_RX_FIFO_0_EL_CNT) ? 0U : (rx_fifo_idx + 1U);
|
||||
can_health[can_number].total_rx_lost_cnt += 1U; // At least one message was lost
|
||||
}
|
||||
@@ -220,6 +215,10 @@ void can_rx(uint8_t can_number) {
|
||||
can_health[can_number].total_fwd_cnt += 1U;
|
||||
}
|
||||
|
||||
#ifdef PANDA_BODY
|
||||
body_can_rx(&to_push);
|
||||
#endif
|
||||
|
||||
safety_rx_invalid += safety_rx_hook(&to_push) ? 0U : 1U;
|
||||
ignition_can_hook(&to_push);
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// IRQs: FDCAN1_IT0, FDCAN1_IT1
|
||||
// FDCAN2_IT0, FDCAN2_IT1
|
||||
// FDCAN3_IT0, FDCAN3_IT1
|
||||
|
||||
#define CANFD
|
||||
|
||||
typedef struct {
|
||||
volatile uint32_t header[2];
|
||||
volatile uint32_t data_word[CANPACKET_DATA_SIZE_MAX/4U];
|
||||
} canfd_fifo;
|
||||
|
||||
#define CANS_ARRAY_SIZE 3
|
||||
extern FDCAN_GlobalTypeDef *cans[CANS_ARRAY_SIZE];
|
||||
|
||||
#define CAN_ACK_ERROR 3U
|
||||
|
||||
void can_clear_send(FDCAN_GlobalTypeDef *FDCANx, uint8_t can_number);
|
||||
void update_can_health_pkt(uint8_t can_number, uint32_t ir_reg);
|
||||
|
||||
// ***************************** CAN *****************************
|
||||
// FDFDCANx_IT1 IRQ Handler (TX)
|
||||
void process_can(uint8_t can_number);
|
||||
// FDFDCANx_IT0 IRQ Handler (RX and errors)
|
||||
// blink blue when we are receiving CAN messages
|
||||
void can_rx(uint8_t can_number);
|
||||
bool can_init(uint8_t can_number);
|
||||
@@ -1,34 +1,32 @@
|
||||
#include "harness_declarations.h"
|
||||
#include "board/drivers/drivers.h"
|
||||
|
||||
struct harness_t harness;
|
||||
|
||||
// The ignition relay is only used for testing purposes
|
||||
void set_intercept_relay(bool intercept, bool ignition_relay) {
|
||||
if (current_board->harness_config->has_harness) {
|
||||
bool drive_relay = intercept;
|
||||
if (harness.status == HARNESS_STATUS_NC) {
|
||||
// no harness, no relay to drive
|
||||
drive_relay = false;
|
||||
}
|
||||
bool drive_relay = intercept;
|
||||
if (harness.status == HARNESS_STATUS_NC) {
|
||||
// no harness, no relay to drive
|
||||
drive_relay = false;
|
||||
}
|
||||
|
||||
if (drive_relay || ignition_relay) {
|
||||
harness.relay_driven = true;
|
||||
}
|
||||
if (drive_relay || ignition_relay) {
|
||||
harness.relay_driven = true;
|
||||
}
|
||||
|
||||
// wait until we're not reading the analog voltages anymore
|
||||
while (harness.sbu_adc_lock) {}
|
||||
// wait until we're not reading the analog voltages anymore
|
||||
while (harness.sbu_adc_lock) {}
|
||||
|
||||
if (harness.status == HARNESS_STATUS_NORMAL) {
|
||||
set_gpio_output(current_board->harness_config->GPIO_relay_SBU1, current_board->harness_config->pin_relay_SBU1, !ignition_relay);
|
||||
set_gpio_output(current_board->harness_config->GPIO_relay_SBU2, current_board->harness_config->pin_relay_SBU2, !drive_relay);
|
||||
} else {
|
||||
set_gpio_output(current_board->harness_config->GPIO_relay_SBU1, current_board->harness_config->pin_relay_SBU1, !drive_relay);
|
||||
set_gpio_output(current_board->harness_config->GPIO_relay_SBU2, current_board->harness_config->pin_relay_SBU2, !ignition_relay);
|
||||
}
|
||||
if (harness.status == HARNESS_STATUS_NORMAL) {
|
||||
set_gpio_output(current_board->harness_config->GPIO_relay_SBU1, current_board->harness_config->pin_relay_SBU1, !ignition_relay);
|
||||
set_gpio_output(current_board->harness_config->GPIO_relay_SBU2, current_board->harness_config->pin_relay_SBU2, !drive_relay);
|
||||
} else {
|
||||
set_gpio_output(current_board->harness_config->GPIO_relay_SBU1, current_board->harness_config->pin_relay_SBU1, !drive_relay);
|
||||
set_gpio_output(current_board->harness_config->GPIO_relay_SBU2, current_board->harness_config->pin_relay_SBU2, !ignition_relay);
|
||||
}
|
||||
|
||||
if (!(drive_relay || ignition_relay)) {
|
||||
harness.relay_driven = false;
|
||||
}
|
||||
if (!(drive_relay || ignition_relay)) {
|
||||
harness.relay_driven = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,13 +54,13 @@ static uint8_t harness_detect_orientation(void) {
|
||||
|
||||
#ifndef BOOTSTUB
|
||||
// We can't detect orientation if the relay is being driven
|
||||
if (!harness.relay_driven && current_board->harness_config->has_harness) {
|
||||
if (!harness.relay_driven) {
|
||||
harness.sbu_adc_lock = true;
|
||||
set_gpio_mode(current_board->harness_config->GPIO_SBU1, current_board->harness_config->pin_SBU1, MODE_ANALOG);
|
||||
set_gpio_mode(current_board->harness_config->GPIO_SBU2, current_board->harness_config->pin_SBU2, MODE_ANALOG);
|
||||
|
||||
harness.sbu1_voltage_mV = adc_get_mV(current_board->harness_config->adc_channel_SBU1);
|
||||
harness.sbu2_voltage_mV = adc_get_mV(current_board->harness_config->adc_channel_SBU2);
|
||||
harness.sbu1_voltage_mV = adc_get_mV(¤t_board->harness_config->adc_signal_SBU1);
|
||||
harness.sbu2_voltage_mV = adc_get_mV(¤t_board->harness_config->adc_signal_SBU2);
|
||||
uint16_t detection_threshold = current_board->avdd_mV / 2U;
|
||||
|
||||
// Detect connection and orientation
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define HARNESS_STATUS_NC 0U
|
||||
#define HARNESS_STATUS_NORMAL 1U
|
||||
#define HARNESS_STATUS_FLIPPED 2U
|
||||
|
||||
struct harness_t {
|
||||
uint8_t status;
|
||||
uint16_t sbu1_voltage_mV;
|
||||
uint16_t sbu2_voltage_mV;
|
||||
bool relay_driven;
|
||||
bool sbu_adc_lock;
|
||||
};
|
||||
extern struct harness_t harness;
|
||||
|
||||
struct harness_configuration {
|
||||
const bool has_harness;
|
||||
GPIO_TypeDef * const GPIO_SBU1;
|
||||
GPIO_TypeDef * const GPIO_SBU2;
|
||||
GPIO_TypeDef * const GPIO_relay_SBU1;
|
||||
GPIO_TypeDef * const GPIO_relay_SBU2;
|
||||
const uint8_t pin_SBU1;
|
||||
const uint8_t pin_SBU2;
|
||||
const uint8_t pin_relay_SBU1;
|
||||
const uint8_t pin_relay_SBU2;
|
||||
const uint8_t adc_channel_SBU1;
|
||||
const uint8_t adc_channel_SBU2;
|
||||
};
|
||||
|
||||
// The ignition relay is only used for testing purposes
|
||||
void set_intercept_relay(bool intercept, bool ignition_relay);
|
||||
bool harness_check_ignition(void);
|
||||
void harness_tick(void);
|
||||
void harness_init(void);
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "interrupts_declarations.h"
|
||||
#include "board/drivers/drivers.h"
|
||||
|
||||
void unused_interrupt_handler(void) {
|
||||
// Something is wrong if this handler is called!
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct interrupt {
|
||||
IRQn_Type irq_type;
|
||||
void (*handler)(void);
|
||||
uint32_t call_counter;
|
||||
uint32_t call_rate;
|
||||
uint32_t max_call_rate; // Call rate is defined as the amount of calls each second
|
||||
uint32_t call_rate_fault;
|
||||
} interrupt;
|
||||
|
||||
void interrupt_timer_init(void);
|
||||
uint32_t microsecond_timer_get(void);
|
||||
void unused_interrupt_handler(void);
|
||||
|
||||
extern interrupt interrupts[NUM_INTERRUPTS];
|
||||
|
||||
#define REGISTER_INTERRUPT(irq_num, func_ptr, call_rate_max, rate_fault) \
|
||||
interrupts[irq_num].irq_type = (irq_num); \
|
||||
interrupts[irq_num].handler = (func_ptr); \
|
||||
interrupts[irq_num].call_counter = 0U; \
|
||||
interrupts[irq_num].call_rate = 0U; \
|
||||
interrupts[irq_num].max_call_rate = (call_rate_max); \
|
||||
interrupts[irq_num].call_rate_fault = (rate_fault);
|
||||
|
||||
extern float interrupt_load;
|
||||
|
||||
void handle_interrupt(IRQn_Type irq_type);
|
||||
// Every second
|
||||
void interrupt_timer_handler(void);
|
||||
void init_interrupts(bool check_rate_limit);
|
||||
@@ -3,7 +3,7 @@
|
||||
#define LED_GREEN 1U
|
||||
#define LED_BLUE 2U
|
||||
|
||||
#define LED_PWM_POWER 5U
|
||||
#define LED_PWM_POWER 2U
|
||||
|
||||
void led_set(uint8_t color, bool enabled) {
|
||||
if (color < 3U) {
|
||||
|
||||
+45
-45
@@ -1,56 +1,56 @@
|
||||
#define PWM_COUNTER_OVERFLOW 2000U // To get ~50kHz
|
||||
#define PWM_COUNTER_OVERFLOW 4800U // To get ~25kHz
|
||||
|
||||
// TODO: Implement for 32-bit timers
|
||||
|
||||
void pwm_init(TIM_TypeDef *TIM, uint8_t channel){
|
||||
// Enable timer and auto-reload
|
||||
register_set(&(TIM->CR1), TIM_CR1_CEN | TIM_CR1_ARPE, 0x3FU);
|
||||
// Enable timer and auto-reload
|
||||
register_set(&(TIM->CR1), TIM_CR1_CEN | TIM_CR1_ARPE, 0x3FU);
|
||||
|
||||
// Set channel as PWM mode 1 and enable output
|
||||
switch(channel){
|
||||
case 1U:
|
||||
register_set_bits(&(TIM->CCMR1), (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1PE));
|
||||
register_set_bits(&(TIM->CCER), TIM_CCER_CC1E);
|
||||
break;
|
||||
case 2U:
|
||||
register_set_bits(&(TIM->CCMR1), (TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2PE));
|
||||
register_set_bits(&(TIM->CCER), TIM_CCER_CC2E);
|
||||
break;
|
||||
case 3U:
|
||||
register_set_bits(&(TIM->CCMR2), (TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3PE));
|
||||
register_set_bits(&(TIM->CCER), TIM_CCER_CC3E);
|
||||
break;
|
||||
case 4U:
|
||||
register_set_bits(&(TIM->CCMR2), (TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4PE));
|
||||
register_set_bits(&(TIM->CCER), TIM_CCER_CC4E);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Set channel as PWM mode 1 and enable output
|
||||
switch(channel){
|
||||
case 1U:
|
||||
register_set_bits(&(TIM->CCMR1), (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1PE));
|
||||
register_set_bits(&(TIM->CCER), TIM_CCER_CC1E);
|
||||
break;
|
||||
case 2U:
|
||||
register_set_bits(&(TIM->CCMR1), (TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2PE));
|
||||
register_set_bits(&(TIM->CCER), TIM_CCER_CC2E);
|
||||
break;
|
||||
case 3U:
|
||||
register_set_bits(&(TIM->CCMR2), (TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3PE));
|
||||
register_set_bits(&(TIM->CCER), TIM_CCER_CC3E);
|
||||
break;
|
||||
case 4U:
|
||||
register_set_bits(&(TIM->CCMR2), (TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4PE));
|
||||
register_set_bits(&(TIM->CCER), TIM_CCER_CC4E);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Set max counter value
|
||||
register_set(&(TIM->ARR), PWM_COUNTER_OVERFLOW, 0xFFFFU);
|
||||
// Set max counter value
|
||||
register_set(&(TIM->ARR), PWM_COUNTER_OVERFLOW, 0xFFFFU);
|
||||
|
||||
// Update registers and clear counter
|
||||
TIM->EGR |= TIM_EGR_UG;
|
||||
// Update registers and clear counter
|
||||
TIM->EGR |= TIM_EGR_UG;
|
||||
}
|
||||
|
||||
void pwm_set(TIM_TypeDef *TIM, uint8_t channel, uint8_t percentage){
|
||||
uint16_t comp_value = (((uint16_t) percentage * PWM_COUNTER_OVERFLOW) / 100U);
|
||||
switch(channel){
|
||||
case 1U:
|
||||
register_set(&(TIM->CCR1), comp_value, 0xFFFFU);
|
||||
break;
|
||||
case 2U:
|
||||
register_set(&(TIM->CCR2), comp_value, 0xFFFFU);
|
||||
break;
|
||||
case 3U:
|
||||
register_set(&(TIM->CCR3), comp_value, 0xFFFFU);
|
||||
break;
|
||||
case 4U:
|
||||
register_set(&(TIM->CCR4), comp_value, 0xFFFFU);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
uint16_t comp_value = (((uint16_t) percentage * PWM_COUNTER_OVERFLOW) / 100U);
|
||||
switch(channel){
|
||||
case 1U:
|
||||
register_set(&(TIM->CCR1), comp_value, 0xFFFFU);
|
||||
break;
|
||||
case 2U:
|
||||
register_set(&(TIM->CCR2), comp_value, 0xFFFFU);
|
||||
break;
|
||||
case 3U:
|
||||
register_set(&(TIM->CCR3), comp_value, 0xFFFFU);
|
||||
break;
|
||||
case 4U:
|
||||
register_set(&(TIM->CCR4), comp_value, 0xFFFFU);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
#include "registers_declarations.h"
|
||||
#include "board/drivers/drivers.h"
|
||||
|
||||
typedef struct reg {
|
||||
volatile uint32_t *address;
|
||||
uint32_t value;
|
||||
uint32_t check_mask;
|
||||
bool logged_fault;
|
||||
} reg;
|
||||
|
||||
#define CHECK_COLLISION(hash, addr) (((uint32_t) register_map[hash].address != 0U) && (register_map[hash].address != (addr)))
|
||||
|
||||
static reg register_map[REGISTER_MAP_SIZE];
|
||||
|
||||
@@ -49,10 +58,13 @@ void check_registers(void){
|
||||
if((uint32_t) register_map[i].address != 0U){
|
||||
ENTER_CRITICAL()
|
||||
if((*(register_map[i].address) & register_map[i].check_mask) != (register_map[i].value & register_map[i].check_mask)){
|
||||
if(!register_map[i].logged_fault){
|
||||
print("Register 0x"); puth((uint32_t) register_map[i].address); print(" divergent! Map: 0x"); puth(register_map[i].value); print(" Reg: 0x"); puth(*(register_map[i].address)); print("\n");
|
||||
register_map[i].logged_fault = true;
|
||||
}
|
||||
#ifdef DEBUG_FAULTS
|
||||
print("Register at address 0x"); puth((uint32_t) register_map[i].address); print(" is divergent!");
|
||||
print(" Map: 0x"); puth(register_map[i].value);
|
||||
print(" Register: 0x"); puth(*(register_map[i].address));
|
||||
print(" Mask: 0x"); puth(register_map[i].check_mask);
|
||||
print("\n");
|
||||
#endif
|
||||
fault_occurred(FAULT_REGISTER_DIVERGENT);
|
||||
}
|
||||
EXIT_CRITICAL()
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct reg {
|
||||
volatile uint32_t *address;
|
||||
uint32_t value;
|
||||
uint32_t check_mask;
|
||||
bool logged_fault;
|
||||
} reg;
|
||||
|
||||
// 10 bit hash with 23 as a prime
|
||||
#define REGISTER_MAP_SIZE 0x3FFU
|
||||
#define HASHING_PRIME 23U
|
||||
#define CHECK_COLLISION(hash, addr) (((uint32_t) register_map[hash].address != 0U) && (register_map[hash].address != (addr)))
|
||||
|
||||
// Do not put bits in the check mask that get changed by the hardware
|
||||
void register_set(volatile uint32_t *addr, uint32_t val, uint32_t mask);
|
||||
// Set individual bits. Also add them to the check_mask.
|
||||
// Do not use this to change bits that get reset by the hardware
|
||||
void register_set_bits(volatile uint32_t *addr, uint32_t val);
|
||||
// Clear individual bits. Also add them to the check_mask.
|
||||
// Do not use this to clear bits that get set by the hardware
|
||||
void register_clear_bits(volatile uint32_t *addr, uint32_t val);
|
||||
// To be called periodically
|
||||
void check_registers(void);
|
||||
void init_registers(void);
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "simple_watchdog_declarations.h"
|
||||
#include "board/drivers/drivers.h"
|
||||
|
||||
static simple_watchdog_state_t wd_state;
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct simple_watchdog_state_t {
|
||||
uint32_t fault;
|
||||
uint32_t last_ts;
|
||||
uint32_t threshold;
|
||||
} simple_watchdog_state_t;
|
||||
|
||||
void simple_watchdog_kick(void);
|
||||
void simple_watchdog_init(uint32_t fault, uint32_t threshold);
|
||||
+28
-13
@@ -1,24 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include "spi_declarations.h"
|
||||
#include "crc.h"
|
||||
#include "board/drivers/drivers.h"
|
||||
|
||||
#ifdef STM32H7
|
||||
#define SPI_BUF_SIZE 2048U
|
||||
// H7 DMA2 located in D2 domain, so we need to use SRAM1/SRAM2
|
||||
#ifdef STM32H7
|
||||
__attribute__((section(".sram12"))) uint8_t spi_buf_rx[SPI_BUF_SIZE];
|
||||
__attribute__((section(".sram12"))) uint8_t spi_buf_tx[SPI_BUF_SIZE];
|
||||
#else
|
||||
#define SPI_BUF_SIZE 1024U
|
||||
uint8_t spi_buf_rx[SPI_BUF_SIZE];
|
||||
uint8_t spi_buf_tx[SPI_BUF_SIZE];
|
||||
#endif
|
||||
|
||||
#define SPI_CHECKSUM_START 0xABU
|
||||
#define SPI_SYNC_BYTE 0x5AU
|
||||
#define SPI_HACK 0x79U
|
||||
#define SPI_DACK 0x85U
|
||||
#define SPI_NACK 0x1FU
|
||||
|
||||
// SPI states
|
||||
enum {
|
||||
SPI_STATE_HEADER,
|
||||
SPI_STATE_HEADER_ACK,
|
||||
SPI_STATE_HEADER_NACK,
|
||||
SPI_STATE_DATA_RX,
|
||||
SPI_STATE_DATA_RX_ACK,
|
||||
SPI_STATE_DATA_TX
|
||||
};
|
||||
|
||||
uint16_t spi_error_count = 0;
|
||||
|
||||
uint16_t spi_checksum_error_count = 0;
|
||||
#define SPI_HEADER_SIZE 7U
|
||||
|
||||
// low level SPI prototypes
|
||||
void llspi_init(void);
|
||||
void llspi_mosi_dma(uint8_t *addr, int len);
|
||||
void llspi_miso_dma(uint8_t *addr, int len);
|
||||
|
||||
#if defined(ENABLE_SPI) || defined(BOOTSTUB)
|
||||
static uint8_t spi_state = SPI_STATE_HEADER;
|
||||
static uint16_t spi_data_len_mosi;
|
||||
static bool spi_can_tx_ready = false;
|
||||
@@ -155,9 +172,12 @@ void spi_rx_done(void) {
|
||||
print("SPI: did expect data for can_write\n");
|
||||
}
|
||||
} else if (spi_endpoint == 0xABU) {
|
||||
// test endpoint, send max response length
|
||||
// test endpoint: mimics panda -> device transfer
|
||||
response_len = spi_data_len_miso;
|
||||
response_ack = true;
|
||||
} else if (spi_endpoint == 0xACU) {
|
||||
// test endpoint: mimics device -> panda transfer (with NACK)
|
||||
response_ack = false;
|
||||
} else {
|
||||
print("SPI: unexpected endpoint"); puth(spi_endpoint); print("\n");
|
||||
}
|
||||
@@ -236,8 +256,3 @@ void spi_tx_done(bool reset) {
|
||||
void can_tx_comms_resume_spi(void) {
|
||||
spi_can_tx_ready = true;
|
||||
}
|
||||
#else
|
||||
void can_tx_comms_resume_spi(void) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "crc.h"
|
||||
|
||||
#define SPI_TIMEOUT_US 10000U
|
||||
|
||||
// got max rate from hitting a non-existent endpoint
|
||||
// in a tight loop, plus some buffer
|
||||
#define SPI_IRQ_RATE 16000U
|
||||
|
||||
#ifdef STM32H7
|
||||
#define SPI_BUF_SIZE 2048U
|
||||
// H7 DMA2 located in D2 domain, so we need to use SRAM1/SRAM2
|
||||
__attribute__((section(".sram12"))) extern uint8_t spi_buf_rx[SPI_BUF_SIZE];
|
||||
__attribute__((section(".sram12"))) extern uint8_t spi_buf_tx[SPI_BUF_SIZE];
|
||||
#else
|
||||
#define SPI_BUF_SIZE 1024U
|
||||
extern uint8_t spi_buf_rx[SPI_BUF_SIZE];
|
||||
extern uint8_t spi_buf_tx[SPI_BUF_SIZE];
|
||||
#endif
|
||||
|
||||
#define SPI_CHECKSUM_START 0xABU
|
||||
#define SPI_SYNC_BYTE 0x5AU
|
||||
#define SPI_HACK 0x79U
|
||||
#define SPI_DACK 0x85U
|
||||
#define SPI_NACK 0x1FU
|
||||
|
||||
// SPI states
|
||||
enum {
|
||||
SPI_STATE_HEADER,
|
||||
SPI_STATE_HEADER_ACK,
|
||||
SPI_STATE_HEADER_NACK,
|
||||
SPI_STATE_DATA_RX,
|
||||
SPI_STATE_DATA_RX_ACK,
|
||||
SPI_STATE_DATA_TX
|
||||
};
|
||||
|
||||
extern uint16_t spi_error_count;
|
||||
|
||||
#define SPI_HEADER_SIZE 7U
|
||||
|
||||
// low level SPI prototypes
|
||||
void llspi_init(void);
|
||||
void llspi_mosi_dma(uint8_t *addr, int len);
|
||||
void llspi_miso_dma(uint8_t *addr, int len);
|
||||
|
||||
void can_tx_comms_resume_spi(void);
|
||||
#if defined(ENABLE_SPI) || defined(BOOTSTUB)
|
||||
void spi_init(void);
|
||||
void spi_rx_done(void);
|
||||
void spi_tx_done(bool reset);
|
||||
#endif
|
||||
@@ -1,6 +1,4 @@
|
||||
#include "uart_declarations.h"
|
||||
|
||||
// IRQs: USART2, USART3, UART5
|
||||
#include "board/drivers/drivers.h"
|
||||
|
||||
// ***************************** Definitions *****************************
|
||||
|
||||
@@ -28,12 +26,7 @@
|
||||
UART_BUFFER(debug, FIFO_SIZE_INT, FIFO_SIZE_INT, USART2, debug_ring_callback, true)
|
||||
|
||||
// SOM debug = UART7
|
||||
#ifdef STM32H7
|
||||
UART_BUFFER(som_debug, FIFO_SIZE_INT, FIFO_SIZE_INT, UART7, NULL, true)
|
||||
#else
|
||||
// UART7 is not available on F4
|
||||
UART_BUFFER(som_debug, 1U, 1U, NULL, NULL, true)
|
||||
#endif
|
||||
UART_BUFFER(som_debug, FIFO_SIZE_INT, FIFO_SIZE_INT, UART7, NULL, true)
|
||||
|
||||
uart_ring *get_ring_by_number(int a) {
|
||||
uart_ring *ring = NULL;
|
||||
@@ -112,15 +105,6 @@ bool put_char(uart_ring *q, char elem) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void clear_uart_buff(uart_ring *q) {
|
||||
ENTER_CRITICAL();
|
||||
q->w_ptr_tx = 0;
|
||||
q->r_ptr_tx = 0;
|
||||
q->w_ptr_rx = 0;
|
||||
q->r_ptr_rx = 0;
|
||||
EXIT_CRITICAL();
|
||||
}
|
||||
|
||||
// ************************ High-level debug functions **********************
|
||||
void putch(const char a) {
|
||||
// misra-c2012-17.7: serial debug function, ok to ignore output
|
||||
@@ -145,14 +129,14 @@ void puth(unsigned int i) {
|
||||
puthx(i, 8U);
|
||||
}
|
||||
|
||||
#if defined(ENABLE_SPI) || defined(BOOTSTUB) || defined(DEBUG)
|
||||
void puth4(unsigned int i) {
|
||||
#if defined(DEBUG_SPI) || defined(BOOTSTUB) || defined(DEBUG)
|
||||
static void puth4(unsigned int i) {
|
||||
puthx(i, 4U);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_SPI) || defined(BOOTSTUB) || defined(DEBUG_USB) || defined(DEBUG_COMMS)
|
||||
void hexdump(const void *a, int l) {
|
||||
#if defined(DEBUG_SPI) || defined(BOOTSTUB) || defined(DEBUG_USB) || defined(DEBUG_COMMS)
|
||||
static void hexdump(const void *a, int l) {
|
||||
if (a != NULL) {
|
||||
for (int i=0; i < l; i++) {
|
||||
if ((i != 0) && ((i & 0xf) == 0)) print("\n");
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// IRQs: USART2, USART3, UART5
|
||||
|
||||
// ***************************** Definitions *****************************
|
||||
#define FIFO_SIZE_INT 0x400U
|
||||
|
||||
typedef struct uart_ring {
|
||||
volatile uint16_t w_ptr_tx;
|
||||
volatile uint16_t r_ptr_tx;
|
||||
uint8_t *elems_tx;
|
||||
uint32_t tx_fifo_size;
|
||||
volatile uint16_t w_ptr_rx;
|
||||
volatile uint16_t r_ptr_rx;
|
||||
uint8_t *elems_rx;
|
||||
uint32_t rx_fifo_size;
|
||||
USART_TypeDef *uart;
|
||||
void (*callback)(struct uart_ring*);
|
||||
bool overwrite;
|
||||
} uart_ring;
|
||||
|
||||
// ***************************** Function prototypes *****************************
|
||||
void debug_ring_callback(uart_ring *ring);
|
||||
void uart_tx_ring(uart_ring *q);
|
||||
uart_ring *get_ring_by_number(int a);
|
||||
// ************************* Low-level buffer functions *************************
|
||||
bool get_char(uart_ring *q, char *elem);
|
||||
bool injectc(uart_ring *q, char elem);
|
||||
bool put_char(uart_ring *q, char elem);
|
||||
void clear_uart_buff(uart_ring *q);
|
||||
// ************************ High-level debug functions **********************
|
||||
void putch(const char a);
|
||||
void print(const char *a);
|
||||
void puthx(uint32_t i, uint8_t len);
|
||||
void puth(unsigned int i);
|
||||
#if defined(ENABLE_SPI) || defined(BOOTSTUB) || defined(DEBUG)
|
||||
void puth4(unsigned int i);
|
||||
#endif
|
||||
void hexdump(const void *a, int l);
|
||||
@@ -1,4 +1,87 @@
|
||||
#include "usb_declarations.h"
|
||||
#include "board/drivers/drivers.h"
|
||||
|
||||
// IRQs: OTG_FS
|
||||
|
||||
typedef union {
|
||||
uint16_t w;
|
||||
struct BW {
|
||||
uint8_t msb;
|
||||
uint8_t lsb;
|
||||
}
|
||||
bw;
|
||||
} uint16_t_uint8_t;
|
||||
|
||||
typedef union _USB_Setup {
|
||||
uint32_t d8[2];
|
||||
struct _SetupPkt_Struc
|
||||
{
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bRequest;
|
||||
uint16_t_uint8_t wValue;
|
||||
uint16_t_uint8_t wIndex;
|
||||
uint16_t_uint8_t wLength;
|
||||
} b;
|
||||
} USB_Setup_TypeDef;
|
||||
|
||||
// **** supporting defines ****
|
||||
#define USB_REQ_GET_STATUS 0x00
|
||||
#define USB_REQ_SET_ADDRESS 0x05
|
||||
#define USB_REQ_GET_DESCRIPTOR 0x06
|
||||
#define USB_REQ_SET_CONFIGURATION 0x09
|
||||
#define USB_REQ_SET_INTERFACE 0x0B
|
||||
|
||||
#define USB_DESC_TYPE_DEVICE 0x01
|
||||
#define USB_DESC_TYPE_CONFIGURATION 0x02
|
||||
#define USB_DESC_TYPE_STRING 0x03
|
||||
#define USB_DESC_TYPE_INTERFACE 0x04
|
||||
#define USB_DESC_TYPE_ENDPOINT 0x05
|
||||
#define USB_DESC_TYPE_DEVICE_QUALIFIER 0x06
|
||||
#define USB_DESC_TYPE_BINARY_OBJECT_STORE 0x0f
|
||||
|
||||
// offsets for configuration strings
|
||||
#define STRING_OFFSET_LANGID 0x00
|
||||
#define STRING_OFFSET_IMANUFACTURER 0x01
|
||||
#define STRING_OFFSET_IPRODUCT 0x02
|
||||
#define STRING_OFFSET_ISERIAL 0x03
|
||||
#define STRING_OFFSET_ICONFIGURATION 0x04
|
||||
|
||||
// WinUSB requests
|
||||
#define WINUSB_REQ_GET_COMPATID_DESCRIPTOR 0x04
|
||||
#define WINUSB_REQ_GET_EXT_PROPS_OS 0x05
|
||||
#define WINUSB_REQ_GET_DESCRIPTOR 0x07
|
||||
|
||||
#define STS_DATA_UPDT 2
|
||||
#define STS_SETUP_UPDT 6
|
||||
|
||||
// for the repeating interfaces
|
||||
#define DSCR_INTERFACE_LEN 9
|
||||
#define DSCR_ENDPOINT_LEN 7
|
||||
#define DSCR_CONFIG_LEN 9
|
||||
#define DSCR_DEVICE_LEN 18
|
||||
|
||||
// endpoint types
|
||||
#define ENDPOINT_TYPE_BULK 2
|
||||
#define ENDPOINT_TYPE_INT 3
|
||||
|
||||
// These are arbitrary values used in bRequest
|
||||
#define MS_VENDOR_CODE 0x20
|
||||
#define WEBUSB_VENDOR_CODE 0x30
|
||||
|
||||
// BOS constants
|
||||
#define BINARY_OBJECT_STORE_DESCRIPTOR_LENGTH 0x05
|
||||
#define BINARY_OBJECT_STORE_DESCRIPTOR 0x0F
|
||||
#define WINUSB_PLATFORM_DESCRIPTOR_LENGTH 0x9E
|
||||
|
||||
// Convert machine byte order to USB byte order
|
||||
#define TOUSBORDER(num)\
|
||||
((num) & 0xFFU), (((uint16_t)(num) >> 8) & 0xFFU)
|
||||
|
||||
// take in string length and return the first 2 bytes of a string descriptor
|
||||
#define STRING_DESCRIPTOR_HEADER(size)\
|
||||
(((((size) * 2) + 2) & 0xFF) | 0x0300)
|
||||
|
||||
#define ENDPOINT_RCV 0x80
|
||||
#define ENDPOINT_SND 0x00
|
||||
|
||||
static uint8_t response[USBPACKET_MAX_SIZE];
|
||||
|
||||
@@ -502,11 +585,8 @@ static void usb_setup(void) {
|
||||
control_req.length = setup.b.wLength.w;
|
||||
|
||||
resp_len = comms_control_handler(&control_req, response);
|
||||
// response pending if -1 was returned
|
||||
if (resp_len != -1) {
|
||||
USB_WritePacket(response, MIN(resp_len, setup.b.wLength.w), 0);
|
||||
USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
}
|
||||
USB_WritePacket(response, MIN(resp_len, setup.b.wLength.w), 0);
|
||||
USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// IRQs: OTG_FS
|
||||
|
||||
typedef union {
|
||||
uint16_t w;
|
||||
struct BW {
|
||||
uint8_t msb;
|
||||
uint8_t lsb;
|
||||
}
|
||||
bw;
|
||||
} uint16_t_uint8_t;
|
||||
|
||||
typedef union _USB_Setup {
|
||||
uint32_t d8[2];
|
||||
struct _SetupPkt_Struc
|
||||
{
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bRequest;
|
||||
uint16_t_uint8_t wValue;
|
||||
uint16_t_uint8_t wIndex;
|
||||
uint16_t_uint8_t wLength;
|
||||
} b;
|
||||
} USB_Setup_TypeDef;
|
||||
|
||||
void usb_init(void);
|
||||
void refresh_can_tx_slots_available(void);
|
||||
|
||||
// **** supporting defines ****
|
||||
#define USB_REQ_GET_STATUS 0x00
|
||||
#define USB_REQ_CLEAR_FEATURE 0x01
|
||||
#define USB_REQ_SET_FEATURE 0x03
|
||||
#define USB_REQ_SET_ADDRESS 0x05
|
||||
#define USB_REQ_GET_DESCRIPTOR 0x06
|
||||
#define USB_REQ_SET_DESCRIPTOR 0x07
|
||||
#define USB_REQ_GET_CONFIGURATION 0x08
|
||||
#define USB_REQ_SET_CONFIGURATION 0x09
|
||||
#define USB_REQ_GET_INTERFACE 0x0A
|
||||
#define USB_REQ_SET_INTERFACE 0x0B
|
||||
#define USB_REQ_SYNCH_FRAME 0x0C
|
||||
|
||||
#define USB_DESC_TYPE_DEVICE 0x01
|
||||
#define USB_DESC_TYPE_CONFIGURATION 0x02
|
||||
#define USB_DESC_TYPE_STRING 0x03
|
||||
#define USB_DESC_TYPE_INTERFACE 0x04
|
||||
#define USB_DESC_TYPE_ENDPOINT 0x05
|
||||
#define USB_DESC_TYPE_DEVICE_QUALIFIER 0x06
|
||||
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 0x07
|
||||
#define USB_DESC_TYPE_BINARY_OBJECT_STORE 0x0f
|
||||
|
||||
// offsets for configuration strings
|
||||
#define STRING_OFFSET_LANGID 0x00
|
||||
#define STRING_OFFSET_IMANUFACTURER 0x01
|
||||
#define STRING_OFFSET_IPRODUCT 0x02
|
||||
#define STRING_OFFSET_ISERIAL 0x03
|
||||
#define STRING_OFFSET_ICONFIGURATION 0x04
|
||||
#define STRING_OFFSET_IINTERFACE 0x05
|
||||
|
||||
// WebUSB requests
|
||||
#define WEBUSB_REQ_GET_URL 0x02
|
||||
|
||||
// WebUSB types
|
||||
#define WEBUSB_DESC_TYPE_URL 0x03
|
||||
#define WEBUSB_URL_SCHEME_HTTPS 0x01
|
||||
#define WEBUSB_URL_SCHEME_HTTP 0x00
|
||||
|
||||
// WinUSB requests
|
||||
#define WINUSB_REQ_GET_COMPATID_DESCRIPTOR 0x04
|
||||
#define WINUSB_REQ_GET_EXT_PROPS_OS 0x05
|
||||
#define WINUSB_REQ_GET_DESCRIPTOR 0x07
|
||||
|
||||
#define STS_GOUT_NAK 1
|
||||
#define STS_DATA_UPDT 2
|
||||
#define STS_XFER_COMP 3
|
||||
#define STS_SETUP_COMP 4
|
||||
#define STS_SETUP_UPDT 6
|
||||
|
||||
// for the repeating interfaces
|
||||
#define DSCR_INTERFACE_LEN 9
|
||||
#define DSCR_ENDPOINT_LEN 7
|
||||
#define DSCR_CONFIG_LEN 9
|
||||
#define DSCR_DEVICE_LEN 18
|
||||
|
||||
// endpoint types
|
||||
#define ENDPOINT_TYPE_CONTROL 0
|
||||
#define ENDPOINT_TYPE_ISO 1
|
||||
#define ENDPOINT_TYPE_BULK 2
|
||||
#define ENDPOINT_TYPE_INT 3
|
||||
|
||||
// These are arbitrary values used in bRequest
|
||||
#define MS_VENDOR_CODE 0x20
|
||||
#define WEBUSB_VENDOR_CODE 0x30
|
||||
|
||||
// BOS constants
|
||||
#define BINARY_OBJECT_STORE_DESCRIPTOR_LENGTH 0x05
|
||||
#define BINARY_OBJECT_STORE_DESCRIPTOR 0x0F
|
||||
#define WINUSB_PLATFORM_DESCRIPTOR_LENGTH 0x9E
|
||||
|
||||
// Convert machine byte order to USB byte order
|
||||
#define TOUSBORDER(num)\
|
||||
((num) & 0xFFU), (((uint16_t)(num) >> 8) & 0xFFU)
|
||||
|
||||
// take in string length and return the first 2 bytes of a string descriptor
|
||||
#define STRING_DESCRIPTOR_HEADER(size)\
|
||||
(((((size) * 2) + 2) & 0xFF) | 0x0300)
|
||||
|
||||
#define ENDPOINT_RCV 0x80
|
||||
#define ENDPOINT_SND 0x00
|
||||
|
||||
// ***************************** USB port *****************************
|
||||
void can_tx_comms_resume_usb(void);
|
||||
@@ -57,9 +57,7 @@ void early_initialization(void) {
|
||||
|
||||
if (enter_bootloader_mode == ENTER_BOOTLOADER_MAGIC) {
|
||||
led_init();
|
||||
#ifdef PANDA
|
||||
current_board->init_bootloader();
|
||||
#endif
|
||||
led_set(LED_GREEN, 1);
|
||||
jump_to_bootloader();
|
||||
}
|
||||
|
||||
@@ -5,9 +5,7 @@
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#define CANFD
|
||||
#define ALLOW_DEBUG
|
||||
#define PANDA
|
||||
|
||||
#define ENTER_CRITICAL() 0
|
||||
#define EXIT_CRITICAL() 0
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
#include "faults_declarations.h"
|
||||
|
||||
uint8_t fault_status = FAULT_STATUS_NONE;
|
||||
uint32_t faults = 0U;
|
||||
|
||||
void fault_occurred(uint32_t fault) {
|
||||
if ((faults & fault) == 0U) {
|
||||
if ((PERMANENT_FAULTS & fault) != 0U) {
|
||||
print("Permanent fault occurred: 0x"); puth(fault); print("\n");
|
||||
fault_status = FAULT_STATUS_PERMANENT;
|
||||
} else {
|
||||
print("Temporary fault occurred: 0x"); puth(fault); print("\n");
|
||||
fault_status = FAULT_STATUS_TEMPORARY;
|
||||
}
|
||||
}
|
||||
faults |= fault;
|
||||
}
|
||||
|
||||
void fault_recovered(uint32_t fault) {
|
||||
if ((PERMANENT_FAULTS & fault) == 0U) {
|
||||
faults &= ~fault;
|
||||
} else {
|
||||
print("Cannot recover from a permanent fault!\n");
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define FAULT_STATUS_NONE 0U
|
||||
#define FAULT_STATUS_TEMPORARY 1U
|
||||
#define FAULT_STATUS_PERMANENT 2U
|
||||
|
||||
// Fault types, matches cereal.log.PandaState.FaultType
|
||||
#define FAULT_RELAY_MALFUNCTION (1UL << 0)
|
||||
#define FAULT_UNUSED_INTERRUPT_HANDLED (1UL << 1)
|
||||
#define FAULT_INTERRUPT_RATE_CAN_1 (1UL << 2)
|
||||
#define FAULT_INTERRUPT_RATE_CAN_2 (1UL << 3)
|
||||
#define FAULT_INTERRUPT_RATE_CAN_3 (1UL << 4)
|
||||
#define FAULT_INTERRUPT_RATE_TACH (1UL << 5)
|
||||
#define FAULT_INTERRUPT_RATE_GMLAN (1UL << 6) // deprecated
|
||||
#define FAULT_INTERRUPT_RATE_INTERRUPTS (1UL << 7)
|
||||
#define FAULT_INTERRUPT_RATE_SPI_DMA (1UL << 8)
|
||||
#define FAULT_INTERRUPT_RATE_SPI_CS (1UL << 9)
|
||||
#define FAULT_INTERRUPT_RATE_UART_1 (1UL << 10)
|
||||
#define FAULT_INTERRUPT_RATE_UART_2 (1UL << 11)
|
||||
#define FAULT_INTERRUPT_RATE_UART_3 (1UL << 12)
|
||||
#define FAULT_INTERRUPT_RATE_UART_5 (1UL << 13)
|
||||
#define FAULT_INTERRUPT_RATE_UART_DMA (1UL << 14)
|
||||
#define FAULT_INTERRUPT_RATE_USB (1UL << 15)
|
||||
#define FAULT_INTERRUPT_RATE_TIM1 (1UL << 16)
|
||||
#define FAULT_INTERRUPT_RATE_TIM3 (1UL << 17)
|
||||
#define FAULT_REGISTER_DIVERGENT (1UL << 18)
|
||||
#define FAULT_INTERRUPT_RATE_KLINE_INIT (1UL << 19)
|
||||
#define FAULT_INTERRUPT_RATE_CLOCK_SOURCE (1UL << 20)
|
||||
#define FAULT_INTERRUPT_RATE_TICK (1UL << 21)
|
||||
#define FAULT_INTERRUPT_RATE_EXTI (1UL << 22)
|
||||
#define FAULT_INTERRUPT_RATE_SPI (1UL << 23)
|
||||
#define FAULT_INTERRUPT_RATE_UART_7 (1UL << 24)
|
||||
#define FAULT_SIREN_MALFUNCTION (1UL << 25)
|
||||
#define FAULT_HEARTBEAT_LOOP_WATCHDOG (1UL << 26)
|
||||
#define FAULT_INTERRUPT_RATE_SOUND_DMA (1UL << 27)
|
||||
|
||||
// Permanent faults
|
||||
#define PERMANENT_FAULTS 0U
|
||||
|
||||
extern uint8_t fault_status;
|
||||
extern uint32_t faults;
|
||||
|
||||
void fault_occurred(uint32_t fault);
|
||||
void fault_recovered(uint32_t fault);
|
||||
@@ -3,7 +3,7 @@ import os
|
||||
import subprocess
|
||||
import argparse
|
||||
|
||||
from panda_tici import Panda
|
||||
from panda import Panda
|
||||
|
||||
board_path = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
|
||||
+3
-12
@@ -1,16 +1,10 @@
|
||||
// from the linker script
|
||||
#ifdef STM32H7
|
||||
#define APP_START_ADDRESS 0x8020000U
|
||||
#elif defined(STM32F4)
|
||||
#define APP_START_ADDRESS 0x8004000U
|
||||
#endif
|
||||
#define APP_START_ADDRESS 0x8020000U
|
||||
|
||||
// flasher state variables
|
||||
uint32_t *prog_ptr = NULL;
|
||||
bool unlocked = false;
|
||||
|
||||
void spi_init(void);
|
||||
|
||||
int comms_control_handler(ControlPacket_t *req, uint8_t *resp) {
|
||||
int resp_len = 0;
|
||||
|
||||
@@ -87,7 +81,7 @@ int comms_control_handler(ControlPacket_t *req, uint8_t *resp) {
|
||||
case 0xd6:
|
||||
COMPILE_TIME_ASSERT(sizeof(gitversion) <= USBPACKET_MAX_SIZE);
|
||||
memcpy(resp, gitversion, sizeof(gitversion));
|
||||
resp_len = sizeof(gitversion);
|
||||
resp_len = sizeof(gitversion) - 1U;
|
||||
break;
|
||||
// **** 0xd8: reset ST
|
||||
case 0xd8:
|
||||
@@ -134,15 +128,12 @@ void soft_flasher_start(void) {
|
||||
gpio_usb_init();
|
||||
led_init();
|
||||
|
||||
// enable USB
|
||||
// enable comms
|
||||
usb_init();
|
||||
|
||||
#ifdef ENABLE_SPI
|
||||
if (current_board->has_spi) {
|
||||
gpio_spi_init();
|
||||
spi_init();
|
||||
}
|
||||
#endif
|
||||
|
||||
// green LED on for flashing
|
||||
led_set(LED_GREEN, 1);
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
gdb-multiarch --eval-command="target extended-remote localhost:3333"
|
||||
@@ -1,6 +1,5 @@
|
||||
// When changing these structs, python/__init__.py needs to be kept up to date!
|
||||
#pragma once
|
||||
|
||||
#define HEALTH_PACKET_VERSION 17
|
||||
struct __attribute__((packed)) health_t {
|
||||
uint32_t uptime_pkt;
|
||||
uint32_t voltage_pkt;
|
||||
@@ -27,9 +26,11 @@ struct __attribute__((packed)) health_t {
|
||||
uint16_t sbu1_voltage_mV;
|
||||
uint16_t sbu2_voltage_mV;
|
||||
uint8_t som_reset_triggered;
|
||||
uint16_t sound_output_level_pkt;
|
||||
uint8_t controls_allowed_lateral_pkt;
|
||||
uint8_t controls_allowed_longitudinal_pkt;
|
||||
};
|
||||
|
||||
#define CAN_HEALTH_PACKET_VERSION 5
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t bus_off;
|
||||
uint32_t bus_off_cnt;
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import os
|
||||
import copy
|
||||
|
||||
Import('build_project', 'base_project_f4', 'base_project_h7')
|
||||
|
||||
build_projects = {
|
||||
"panda_jungle": base_project_f4,
|
||||
"panda_jungle_h7": base_project_h7,
|
||||
}
|
||||
|
||||
for project_name, project in build_projects.items():
|
||||
flags = [
|
||||
"-DPANDA_JUNGLE",
|
||||
]
|
||||
if os.getenv("FINAL_PROVISIONING"):
|
||||
flags += ["-DFINAL_PROVISIONING"]
|
||||
|
||||
build_project(project_name, project, flags)
|
||||
@@ -3,11 +3,11 @@ import os
|
||||
import struct
|
||||
from functools import wraps
|
||||
|
||||
from panda_tici import Panda, PandaDFU
|
||||
from panda_tici.python.constants import McuType
|
||||
from panda import Panda, PandaDFU
|
||||
from panda.python.constants import McuType, compute_version_hash
|
||||
|
||||
BASEDIR = os.path.dirname(os.path.realpath(__file__))
|
||||
FW_PATH = os.path.join(BASEDIR, "obj/")
|
||||
FW_PATH = os.path.join(BASEDIR, "../obj/")
|
||||
|
||||
|
||||
def ensure_jungle_health_packet_version(fn):
|
||||
@@ -23,7 +23,7 @@ def ensure_jungle_health_packet_version(fn):
|
||||
|
||||
class PandaJungleDFU(PandaDFU):
|
||||
def recover(self):
|
||||
fn = os.path.join(FW_PATH, self.get_mcu_type().config.bootstub_fn.replace("panda", "panda_jungle"))
|
||||
fn = os.path.join(FW_PATH, self._mcu_type.config.bootstub_fn.replace("panda", "panda_jungle"))
|
||||
with open(fn, "rb") as f:
|
||||
code = f.read()
|
||||
self.program_bootstub(code)
|
||||
@@ -34,13 +34,12 @@ class PandaJungle(Panda):
|
||||
USB_PIDS = (0xddef, 0xddcf)
|
||||
|
||||
HW_TYPE_UNKNOWN = b'\x00'
|
||||
HW_TYPE_V1 = b'\x01'
|
||||
HW_TYPE_V2 = b'\x02'
|
||||
|
||||
F4_DEVICES = [HW_TYPE_V1, ]
|
||||
H7_DEVICES = [HW_TYPE_V2, ]
|
||||
SUPPORTED_DEVICES = H7_DEVICES
|
||||
|
||||
HEALTH_PACKET_VERSION = 1
|
||||
HEALTH_PACKET_VERSION = compute_version_hash(os.path.join(BASEDIR, "jungle_health.h"))
|
||||
HEALTH_STRUCT = struct.Struct("<IffffffHHHHHHHHHHHH")
|
||||
|
||||
HARNESS_ORIENTATION_NONE = 0
|
||||
@@ -53,7 +52,7 @@ class PandaJungle(Panda):
|
||||
|
||||
def flash(self, fn=None, code=None, reconnect=True):
|
||||
if not fn:
|
||||
fn = os.path.join(FW_PATH, self.get_mcu_type().config.app_fn.replace("panda", "panda_jungle"))
|
||||
fn = os.path.join(FW_PATH, McuType.H7.config.app_fn.replace("panda", "panda_jungle"))
|
||||
super().flash(fn=fn, code=code, reconnect=reconnect)
|
||||
|
||||
def recover(self, timeout: int | None = 60, reset: bool = True) -> bool:
|
||||
@@ -74,23 +73,9 @@ class PandaJungle(Panda):
|
||||
self.flash()
|
||||
return True
|
||||
|
||||
def get_mcu_type(self) -> McuType:
|
||||
hw_type = self.get_type()
|
||||
if hw_type in PandaJungle.F4_DEVICES:
|
||||
return McuType.F4
|
||||
elif hw_type in PandaJungle.H7_DEVICES:
|
||||
return McuType.H7
|
||||
else:
|
||||
# have to assume F4, see comment in Panda.connect
|
||||
# initially Jungle V1 has HW type: bytearray(b'')
|
||||
if hw_type == b'' or self._assume_f4_mcu:
|
||||
return McuType.F4
|
||||
|
||||
raise ValueError(f"unknown HW type: {hw_type}")
|
||||
|
||||
def up_to_date(self, fn=None) -> bool:
|
||||
if fn is None:
|
||||
fn = os.path.join(FW_PATH, self.get_mcu_type().config.app_fn.replace("panda", "panda_jungle"))
|
||||
fn = os.path.join(FW_PATH, McuType.H7.config.app_fn.replace("panda", "panda_jungle"))
|
||||
return super().up_to_date(fn=fn)
|
||||
|
||||
# ******************* health *******************
|
||||
@@ -123,13 +108,11 @@ class PandaJungle(Panda):
|
||||
|
||||
# ******************* control *******************
|
||||
|
||||
# Returns tuple with health packet version and CAN packet/USB packet version
|
||||
def get_packets_versions(self):
|
||||
dat = self._handle.controlRead(PandaJungle.REQUEST_IN, 0xdd, 0, 0, 3)
|
||||
if dat and len(dat) == 3:
|
||||
a = struct.unpack("BBB", dat)
|
||||
return (a[0], a[1], a[2])
|
||||
return (-1, -1, -1)
|
||||
dat = self._handle.controlRead(PandaJungle.REQUEST_IN, 0xdd, 0, 0, 8)
|
||||
if dat and len(dat) == 8:
|
||||
return struct.unpack("<II", dat)
|
||||
return (0, 0)
|
||||
|
||||
# ******************* jungle stuff *******************
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
typedef void (*board_init)(void);
|
||||
typedef void (*board_board_tick)(void);
|
||||
typedef bool (*board_get_button)(void);
|
||||
typedef void (*board_init_bootloader)(void);
|
||||
typedef void (*board_set_panda_power)(bool enabled);
|
||||
typedef void (*board_set_panda_individual_power)(uint8_t port_num, bool enabled);
|
||||
typedef void (*board_set_ignition)(bool enabled);
|
||||
@@ -17,12 +18,11 @@ struct board {
|
||||
GPIO_TypeDef * const led_GPIO[3];
|
||||
const uint8_t led_pin[3];
|
||||
const uint8_t led_pwm_channels[3]; // leave at 0 to disable PWM
|
||||
const bool has_canfd;
|
||||
const bool has_sbu_sense;
|
||||
const uint16_t avdd_mV;
|
||||
board_init init;
|
||||
board_board_tick board_tick;
|
||||
board_get_button get_button;
|
||||
board_init_bootloader init_bootloader;
|
||||
board_set_panda_power set_panda_power;
|
||||
board_set_panda_individual_power set_panda_individual_power;
|
||||
board_set_ignition set_ignition;
|
||||
@@ -40,7 +40,6 @@ struct board {
|
||||
|
||||
// ******************* Definitions ********************
|
||||
#define HW_TYPE_UNKNOWN 0U
|
||||
#define HW_TYPE_V1 1U
|
||||
#define HW_TYPE_V2 2U
|
||||
|
||||
// CAN modes
|
||||
@@ -59,18 +58,3 @@ struct board {
|
||||
uint8_t harness_orientation = HARNESS_ORIENTATION_NONE;
|
||||
uint8_t can_mode = CAN_MODE_NORMAL;
|
||||
uint8_t ignition = 0U;
|
||||
|
||||
|
||||
void unused_set_individual_ignition(uint8_t bitmask) {
|
||||
UNUSED(bitmask);
|
||||
}
|
||||
|
||||
void unused_board_enable_header_pin(uint8_t pin_num, bool enabled) {
|
||||
UNUSED(pin_num);
|
||||
UNUSED(enabled);
|
||||
}
|
||||
|
||||
void unused_set_panda_individual_power(uint8_t port_num, bool enabled) {
|
||||
UNUSED(port_num);
|
||||
UNUSED(enabled);
|
||||
}
|
||||
|
||||
@@ -1,158 +0,0 @@
|
||||
// ///////////////////////// //
|
||||
// Jungle board v1 (STM32F4) //
|
||||
// ///////////////////////// //
|
||||
|
||||
void board_v1_enable_can_transceiver(uint8_t transceiver, bool enabled) {
|
||||
switch (transceiver) {
|
||||
case 1U:
|
||||
set_gpio_output(GPIOC, 1, !enabled);
|
||||
break;
|
||||
case 2U:
|
||||
set_gpio_output(GPIOC, 13, !enabled);
|
||||
break;
|
||||
case 3U:
|
||||
set_gpio_output(GPIOA, 0, !enabled);
|
||||
break;
|
||||
case 4U:
|
||||
set_gpio_output(GPIOB, 10, !enabled);
|
||||
break;
|
||||
default:
|
||||
print("Invalid CAN transceiver ("); puth(transceiver); print("): enabling failed\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void board_v1_set_can_mode(uint8_t mode) {
|
||||
board_v1_enable_can_transceiver(2U, false);
|
||||
board_v1_enable_can_transceiver(4U, false);
|
||||
switch (mode) {
|
||||
case CAN_MODE_NORMAL:
|
||||
print("Setting normal CAN mode\n");
|
||||
// B12,B13: disable OBD mode
|
||||
set_gpio_mode(GPIOB, 12, MODE_INPUT);
|
||||
set_gpio_mode(GPIOB, 13, MODE_INPUT);
|
||||
|
||||
// B5,B6: normal CAN2 mode
|
||||
set_gpio_alternate(GPIOB, 5, GPIO_AF9_CAN2);
|
||||
set_gpio_alternate(GPIOB, 6, GPIO_AF9_CAN2);
|
||||
can_mode = CAN_MODE_NORMAL;
|
||||
board_v1_enable_can_transceiver(2U, true);
|
||||
break;
|
||||
case CAN_MODE_OBD_CAN2:
|
||||
print("Setting OBD CAN mode\n");
|
||||
// B5,B6: disable normal CAN2 mode
|
||||
set_gpio_mode(GPIOB, 5, MODE_INPUT);
|
||||
set_gpio_mode(GPIOB, 6, MODE_INPUT);
|
||||
|
||||
// B12,B13: OBD mode
|
||||
set_gpio_alternate(GPIOB, 12, GPIO_AF9_CAN2);
|
||||
set_gpio_alternate(GPIOB, 13, GPIO_AF9_CAN2);
|
||||
can_mode = CAN_MODE_OBD_CAN2;
|
||||
board_v1_enable_can_transceiver(4U, true);
|
||||
break;
|
||||
default:
|
||||
print("Tried to set unsupported CAN mode: "); puth(mode); print("\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void board_v1_set_harness_orientation(uint8_t orientation) {
|
||||
switch (orientation) {
|
||||
case HARNESS_ORIENTATION_NONE:
|
||||
set_gpio_output(GPIOA, 2, false);
|
||||
set_gpio_output(GPIOA, 3, false);
|
||||
set_gpio_output(GPIOA, 4, false);
|
||||
set_gpio_output(GPIOA, 5, false);
|
||||
harness_orientation = orientation;
|
||||
break;
|
||||
case HARNESS_ORIENTATION_1:
|
||||
set_gpio_output(GPIOA, 2, false);
|
||||
set_gpio_output(GPIOA, 3, (ignition != 0U));
|
||||
set_gpio_output(GPIOA, 4, true);
|
||||
set_gpio_output(GPIOA, 5, false);
|
||||
harness_orientation = orientation;
|
||||
break;
|
||||
case HARNESS_ORIENTATION_2:
|
||||
set_gpio_output(GPIOA, 2, (ignition != 0U));
|
||||
set_gpio_output(GPIOA, 3, false);
|
||||
set_gpio_output(GPIOA, 4, false);
|
||||
set_gpio_output(GPIOA, 5, true);
|
||||
harness_orientation = orientation;
|
||||
break;
|
||||
default:
|
||||
print("Tried to set an unsupported harness orientation: "); puth(orientation); print("\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool panda_power = false;
|
||||
void board_v1_set_panda_power(bool enable) {
|
||||
panda_power = enable;
|
||||
set_gpio_output(GPIOB, 14, enable);
|
||||
}
|
||||
|
||||
bool board_v1_get_button(void) {
|
||||
return get_gpio_input(GPIOC, 8);
|
||||
}
|
||||
|
||||
void board_v1_set_ignition(bool enabled) {
|
||||
ignition = enabled ? 0xFFU : 0U;
|
||||
board_v1_set_harness_orientation(harness_orientation);
|
||||
}
|
||||
|
||||
float board_v1_get_channel_power(uint8_t channel) {
|
||||
UNUSED(channel);
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
uint16_t board_v1_get_sbu_mV(uint8_t channel, uint8_t sbu) {
|
||||
UNUSED(channel); UNUSED(sbu);
|
||||
return 0U;
|
||||
}
|
||||
|
||||
void board_v1_init(void) {
|
||||
common_init_gpio();
|
||||
|
||||
// A8,A15: normal CAN3 mode
|
||||
set_gpio_alternate(GPIOA, 8, GPIO_AF11_CAN3);
|
||||
set_gpio_alternate(GPIOA, 15, GPIO_AF11_CAN3);
|
||||
|
||||
board_v1_set_can_mode(CAN_MODE_NORMAL);
|
||||
|
||||
// Enable CAN transceivers
|
||||
for(uint8_t i = 1; i <= 4; i++) {
|
||||
board_v1_enable_can_transceiver(i, true);
|
||||
}
|
||||
|
||||
// Set normal CAN mode
|
||||
board_v1_set_can_mode(CAN_MODE_NORMAL);
|
||||
|
||||
// Set to no harness orientation
|
||||
board_v1_set_harness_orientation(HARNESS_ORIENTATION_NONE);
|
||||
|
||||
// Enable panda power by default
|
||||
board_v1_set_panda_power(true);
|
||||
}
|
||||
|
||||
void board_v1_tick(void) {}
|
||||
|
||||
board board_v1 = {
|
||||
.has_canfd = false,
|
||||
.has_sbu_sense = false,
|
||||
.avdd_mV = 3300U,
|
||||
.init = &board_v1_init,
|
||||
.led_GPIO = {GPIOC, GPIOC, GPIOC},
|
||||
.led_pin = {9, 7, 6},
|
||||
.board_tick = &board_v1_tick,
|
||||
.get_button = &board_v1_get_button,
|
||||
.set_panda_power = &board_v1_set_panda_power,
|
||||
.set_panda_individual_power = &unused_set_panda_individual_power,
|
||||
.set_ignition = &board_v1_set_ignition,
|
||||
.set_individual_ignition = &unused_set_individual_ignition,
|
||||
.set_harness_orientation = &board_v1_set_harness_orientation,
|
||||
.set_can_mode = &board_v1_set_can_mode,
|
||||
.enable_can_transceiver = &board_v1_enable_can_transceiver,
|
||||
.enable_header_pin = &unused_board_enable_header_pin,
|
||||
.get_channel_power = &board_v1_get_channel_power,
|
||||
.get_sbu_mV = &board_v1_get_sbu_mV,
|
||||
};
|
||||
@@ -2,6 +2,8 @@
|
||||
// Jungle board v2 (STM32H7) //
|
||||
// ///////////////////////// //
|
||||
|
||||
#define ADC_CHANNEL(a, c) {.adc = (a), .channel = (c), .sample_time = SAMPLETIME_810_CYCLES, .oversampling = OVERSAMPLING_1}
|
||||
|
||||
gpio_t power_pins[] = {
|
||||
{.bank = GPIOA, .pin = 0},
|
||||
{.bank = GPIOA, .pin = 1},
|
||||
@@ -47,22 +49,22 @@ gpio_t sbu2_relay_pins[] = {
|
||||
{.bank = GPIOE, .pin = 12},
|
||||
};
|
||||
|
||||
adc_channel_t sbu1_channels[] = {
|
||||
{.adc = ADC3, .channel = 12},
|
||||
{.adc = ADC3, .channel = 2},
|
||||
{.adc = ADC3, .channel = 4},
|
||||
{.adc = ADC3, .channel = 6},
|
||||
{.adc = ADC3, .channel = 8},
|
||||
{.adc = ADC3, .channel = 10},
|
||||
const adc_signal_t sbu1_channels[] = {
|
||||
ADC_CHANNEL(ADC3, 12),
|
||||
ADC_CHANNEL(ADC3, 2),
|
||||
ADC_CHANNEL(ADC3, 4),
|
||||
ADC_CHANNEL(ADC3, 6),
|
||||
ADC_CHANNEL(ADC3, 8),
|
||||
ADC_CHANNEL(ADC3, 10),
|
||||
};
|
||||
|
||||
adc_channel_t sbu2_channels[] = {
|
||||
{.adc = ADC1, .channel = 13},
|
||||
{.adc = ADC3, .channel = 3},
|
||||
{.adc = ADC3, .channel = 5},
|
||||
{.adc = ADC3, .channel = 7},
|
||||
{.adc = ADC3, .channel = 9},
|
||||
{.adc = ADC3, .channel = 11},
|
||||
const adc_signal_t sbu2_channels[] = {
|
||||
ADC_CHANNEL(ADC1, 13),
|
||||
ADC_CHANNEL(ADC3, 3),
|
||||
ADC_CHANNEL(ADC3, 5),
|
||||
ADC_CHANNEL(ADC3, 7),
|
||||
ADC_CHANNEL(ADC3, 9),
|
||||
ADC_CHANNEL(ADC3, 11),
|
||||
};
|
||||
|
||||
void board_v2_set_harness_orientation(uint8_t orientation) {
|
||||
@@ -204,8 +206,7 @@ void board_v2_set_individual_ignition(uint8_t bitmask) {
|
||||
float board_v2_get_channel_power(uint8_t channel) {
|
||||
float ret = 0.0f;
|
||||
if ((channel >= 1U) && (channel <= 6U)) {
|
||||
uint16_t readout = adc_get_mV(ADC1, channel - 1U); // these are mapped nicely in hardware
|
||||
|
||||
uint16_t readout = adc_get_mV(&(const adc_signal_t) ADC_CHANNEL(ADC1, channel - 1U)); // these are mapped nicely in hardware
|
||||
ret = (((float) readout / 33e6) - 0.8e-6) / 52e-6 * 12.0f;
|
||||
} else {
|
||||
print("Invalid channel ("); puth(channel); print(")\n");
|
||||
@@ -218,10 +219,10 @@ uint16_t board_v2_get_sbu_mV(uint8_t channel, uint8_t sbu) {
|
||||
if ((channel >= 1U) && (channel <= 6U)) {
|
||||
switch(sbu){
|
||||
case SBU1:
|
||||
ret = adc_get_mV(sbu1_channels[channel - 1U].adc, sbu1_channels[channel - 1U].channel);
|
||||
ret = adc_get_mV(&sbu1_channels[channel - 1U]);
|
||||
break;
|
||||
case SBU2:
|
||||
ret = adc_get_mV(sbu2_channels[channel - 1U].adc, sbu2_channels[channel - 1U].channel);
|
||||
ret = adc_get_mV(&sbu2_channels[channel - 1U]);
|
||||
break;
|
||||
default:
|
||||
print("Invalid SBU ("); puth(sbu); print(")\n");
|
||||
@@ -287,10 +288,9 @@ void board_v2_init(void) {
|
||||
void board_v2_tick(void) {}
|
||||
|
||||
board board_v2 = {
|
||||
.has_canfd = true,
|
||||
.has_sbu_sense = true,
|
||||
.avdd_mV = 3300U,
|
||||
.init = &board_v2_init,
|
||||
.init_bootloader = &board_v2_tick,
|
||||
.led_GPIO = {GPIOE, GPIOE, GPIOE},
|
||||
.led_pin = {4, 3, 2},
|
||||
.board_tick = &board_v2_tick,
|
||||
|
||||
@@ -3,7 +3,7 @@ import os
|
||||
import subprocess
|
||||
import argparse
|
||||
|
||||
from panda_tici import PandaJungle
|
||||
from panda import PandaJungle
|
||||
|
||||
board_path = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
@@ -12,7 +12,7 @@ if __name__ == "__main__":
|
||||
parser.add_argument("--all", action="store_true", help="Recover all panda jungle devices")
|
||||
args = parser.parse_args()
|
||||
|
||||
subprocess.check_call(f"scons -C {board_path}/.. -u -j$(nproc) {board_path}", shell=True)
|
||||
subprocess.check_call(f"scons -C {board_path}/.. -u -j$(nproc) .", shell=True)
|
||||
|
||||
if args.all:
|
||||
serials = PandaJungle.list()
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// When changing these structs, python/__init__.py needs to be kept up to date!
|
||||
|
||||
#define JUNGLE_HEALTH_PACKET_VERSION 1
|
||||
struct __attribute__((packed)) jungle_health_t {
|
||||
uint32_t uptime_pkt;
|
||||
float ch1_power;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user