forked from vedderb/bldc
-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathutils_sys.c
168 lines (145 loc) · 4.02 KB
/
utils_sys.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/*
Copyright 2016 - 2019 Benjamin Vedder [email protected]
This file is part of the VESC firmware.
The VESC firmware is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The VESC firmware is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "utils_sys.h"
#include "hal.h"
#include "app.h"
#include <math.h>
#include <string.h>
#include <stdlib.h>
// Private variables
static volatile int sys_lock_cnt = 0;
/**
* A system locking function with a counter. For every lock, a corresponding unlock must
* exist to unlock the system. That means, if lock is called five times, unlock has to
* be called five times as well. Note that chSysLock and chSysLockFromIsr are the same
* for this port.
*/
void utils_sys_lock_cnt(void) {
if (!sys_lock_cnt) {
chSysLock();
}
sys_lock_cnt++;
}
/**
* A system unlocking function with a counter. For every lock, a corresponding unlock must
* exist to unlock the system. That means, if lock is called five times, unlock has to
* be called five times as well. Note that chSysUnlock and chSysUnlockFromIsr are the same
* for this port.
*/
void utils_sys_unlock_cnt(void) {
if (sys_lock_cnt) {
sys_lock_cnt--;
if (!sys_lock_cnt) {
chSysUnlock();
}
}
}
/**
* Get ID of second motor.
*
* @return
* id for second motor. -1 if this hardware only has one motor.
*/
uint8_t utils_second_motor_id(void) {
#ifdef HW_HAS_DUAL_MOTORS
uint8_t id_next = app_get_configuration()->controller_id + 1;
if (id_next == 255) {
id_next = 0;
}
return id_next;
#else
return 0;
#endif
}
/**
* Read hall sensors
*
* @param is_second_motor
* Use hall sensor port for second motor on dual motor hardware.
*
* @param samples
* The number of extra samples to read and filter over. If this
* is 0, only one sample will be used.
*
* @return
* The state of the three hall sensors.
*/
int utils_read_hall(bool is_second_motor, int samples) {
samples = 1 + 2 * samples;
int h1 = 0, h2 = 0, h3 = 0;
int tres = samples / 2;
if (is_second_motor) {
while (samples--) {
h1 += READ_HALL1_2();
h2 += READ_HALL2_2();
h3 += READ_HALL3_2();
}
} else {
while (samples--) {
h1 += READ_HALL1();
h2 += READ_HALL2();
h3 += READ_HALL3();
}
}
return (h1 > tres) | ((h2 > tres) << 1) | ((h3 > tres) << 2);
}
const char* utils_hw_type_to_string(HW_TYPE hw) {
switch (hw) {
case HW_TYPE_VESC: return "HW_TYPE_VESC"; break;
case HW_TYPE_VESC_BMS: return "HW_TYPE_VESC_BMS"; break;
case HW_TYPE_CUSTOM_MODULE: return "HW_TYPE_CUSTOM_MODULE"; break;
default: return "FAULT_HARDWARE"; break;
}
}
/**
* Check the minimum stack tp had left by counting the remaining fill characters.
*/
int utils_check_min_stack_left(thread_t *tp) {
uint32_t *p = (uint32_t *)tp->p_stklimit;
int free = 0;
while (free < 8192) {
if (*p++ != 0x55555555) {
break;
}
free += sizeof(uint32_t);
}
return free;
}
/*
* Check how much stack the current thread has left now.
*/
int utils_stack_left_now(void) {
struct port_intctx *r13 = (struct port_intctx *)__get_PSP();
return ((stkalign_t *)(r13 - 1) - chThdGetSelfX()->p_stklimit) * sizeof(stkalign_t);
}
/*
* Check if function is on a valid address
*/
bool utils_is_func_valid(void *addr) {
bool res = false;
// Flash
if ((uint32_t)addr >= 0x08000000 && (uint32_t)addr <= (0x08000000 + 1024 * 1024)) {
res = true;
}
// Ram
if ((uint32_t)addr >= 0x20000000 && (uint32_t)addr <= (0x20000000 + 1024 * 128)) {
res = true;
}
// CCM
if ((uint32_t)addr >= 0x10000000 && (uint32_t)addr <= (0x10000000 + 1024 * 64)) {
res = true;
}
return res;
}