-
Notifications
You must be signed in to change notification settings - Fork 25
/
current_monitor.c
130 lines (117 loc) · 3.67 KB
/
current_monitor.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
#include "current_monitor.h"
#include "hal.h"
#include "hw_conf.h"
#include "config.h"
#include "power.h"
#include "faults.h"
#include <math.h>
#define I2C_ADDRESS 0x40
static void curr_alert(EXTDriver *extp, expchannel_t channel);
static const EXTConfig extcfg = {
{
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOB, curr_alert},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL}
}
};
static volatile Config *config;
static volatile float current;
static volatile float coulomb_count;
static volatile float voltage;
static volatile float power;
void current_monitor_init(void)
{
config = config_get_configuration();
extStart(&EXTD1, &extcfg);
extChannelEnable(&EXTD1, 12);
uint8_t tx[3];
uint8_t rx[2];
uint16_t current_cal = 4183;
tx[0] = 0x05;
tx[1] = (uint8_t)(current_cal >> 7);
tx[2] = (uint8_t)((current_cal & 0xFF) << 1);
i2cMasterTransmitTimeout(&I2C_DEV, I2C_ADDRESS, tx, 3, rx, 0, MS2ST(10));
current_monitor_set_overcurrent(config->maxCurrentCutoff);
tx[0] = 0x09;
tx[1] = 0x00;
tx[2] = 0x80;
i2cMasterTransmitTimeout(&I2C_DEV, I2C_ADDRESS, tx, 3, rx, 0, MS2ST(10));
}
void current_monitor_update(void)
{
i2cAcquireBus(&I2C_DEV);
uint8_t tx[1];
uint8_t rx[2];
/*tx[0] = 0x04;*/
/*i2cMasterTransmitTimeout(&I2C_DEV, I2C_ADDRESS, tx, 1, rx, 2, MS2ST(10));*/
/*int16_t current_value = (rx[0] << 8) | rx[1];*/
/*current = current_value * 0.01958504192;*/
tx[0] = 0x01;
i2cMasterTransmitTimeout(&I2C_DEV, I2C_ADDRESS, tx, 1, rx, 2, MS2ST(10));
int16_t shunt_value = (rx[0] << 8) | rx[1];
float shunt_voltage = shunt_value * 1.0e-5;
current = shunt_voltage / 0.0005;
tx[0] = 0x02;
i2cMasterTransmitTimeout(&I2C_DEV, I2C_ADDRESS, tx, 1, rx, 2, MS2ST(10));
int16_t voltage_value = (rx[0] << 6) | (rx[1] >> 2);
voltage = voltage_value * 0.004;
i2cReleaseBus(&I2C_DEV);
if (current > config->maxCurrentCutoff || !palReadPad(CURR_ALERT_GPIO, CURR_ALERT_PIN))
{
power_disable_discharge();
faults_set_fault(FAULT_OVERCURRENT);
}
}
float current_monitor_get_current(void)
{
return current;
}
float current_monitor_get_bus_voltage(void)
{
return voltage;
}
float current_monitor_get_power(void)
{
return power;
}
static void curr_alert(EXTDriver *extp, expchannel_t channel) {
(void)extp;
(void)channel;
chSysLockFromISR();
power_disable_discharge();
faults_set_fault(FAULT_OVERCURRENT);
chSysUnlockFromISR();
}
void current_monitor_set_overcurrent(float current_threshold)
{
i2cAcquireBus(&I2C_DEV);
int8_t value_max = ceil(current_threshold * 0.0005 / 0.00256);
int8_t value_min = -value_max;
uint8_t tx[3];
uint8_t rx[2];
tx[0] = 0x06;
tx[1] = *(uint8_t*)&value_max;
tx[2] = *(uint8_t*)&value_min;
i2cMasterTransmitTimeout(&I2C_DEV, I2C_ADDRESS, tx, 3, rx, 0, MS2ST(10));
i2cReleaseBus(&I2C_DEV);
}