mirror of https://github.com/rusefi/bldc.git
144 lines
3.7 KiB
C
144 lines
3.7 KiB
C
/*
|
|
Copyright 2020 Benjamin Vedder benjamin@vedder.se
|
|
|
|
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 "si8900.h"
|
|
#include "conf_general.h"
|
|
#include "terminal.h"
|
|
#include "commands.h"
|
|
|
|
#ifdef HW_HAS_SI8900
|
|
|
|
// Private variables
|
|
static THD_FUNCTION(si_read_thread, arg);
|
|
static THD_WORKING_AREA(si_read_thread_wa, 256);
|
|
static volatile float m_voltages[3];
|
|
|
|
// Private functions
|
|
static void terminal_read(int argc, const char **argv);
|
|
|
|
static SerialConfig uart_cfg = {
|
|
115200,
|
|
0,
|
|
USART_CR2_LINEN,
|
|
0
|
|
};
|
|
|
|
void si8900_init(void) {
|
|
sdStart(&HW_SI8900_DEV, &uart_cfg);
|
|
palSetPadMode(HW_SI8900_TX_PORT, HW_SI8900_TX_PIN, PAL_MODE_ALTERNATE(HW_SI8900_GPIO_AF) |
|
|
PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUDR_PULLUP);
|
|
palSetPadMode(HW_SI8900_RX_PORT, HW_SI8900_RX_PIN, PAL_MODE_ALTERNATE(HW_SI8900_GPIO_AF) |
|
|
PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUDR_PULLUP);
|
|
chThdCreateStatic(si_read_thread_wa, sizeof(si_read_thread_wa), NORMALPRIO, si_read_thread, NULL);
|
|
|
|
terminal_register_command_callback(
|
|
"si8900_read",
|
|
"Read and print ADC values for 10 seconds.",
|
|
0,
|
|
terminal_read);
|
|
}
|
|
|
|
float si8900_get_voltage(int channel) {
|
|
float res = -1.0;
|
|
|
|
if (channel >= 0 && channel < 3) {
|
|
res = m_voltages[channel];
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
float si8900_get_val_rel(int channel) {
|
|
return si8900_get_voltage(channel) / 3.3;
|
|
}
|
|
|
|
static void terminal_read(int argc, const char **argv) {
|
|
(void)argc;
|
|
(void)argv;
|
|
|
|
for (int i = 0;i < 100;i++) {
|
|
commands_printf("[IN0 IN1 IN2] = [%.3f %.3f %.3f]",
|
|
(double)si8900_get_voltage(0),
|
|
(double)si8900_get_voltage(1),
|
|
(double)si8900_get_voltage(2));
|
|
chThdSleepMilliseconds(100);
|
|
}
|
|
|
|
commands_printf("Done\n");
|
|
}
|
|
|
|
static THD_FUNCTION(si_read_thread, arg) {
|
|
(void)arg;
|
|
chRegSetThreadName("SI8900");
|
|
|
|
while(!chThdShouldTerminateX()) {
|
|
uint8_t txb[1];
|
|
size_t tx_len = 1;
|
|
uint8_t rxb[3];
|
|
size_t rx_len = 3;
|
|
|
|
// Baud rate adjustment
|
|
txb[0] = 0xAA;
|
|
tx_len = 1;
|
|
for (int i = 0;i < 4;i++) {
|
|
sdWriteTimeout(&HW_SI8900_DEV, txb, tx_len, MS2ST(10));
|
|
rx_len = 1;
|
|
size_t res = sdReadTimeout(&HW_SI8900_DEV, rxb, rx_len, 5);
|
|
if (res == rx_len && rxb[0] == 0x55) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (int i = 0;i < 3;i++) {
|
|
if (i == 0) {
|
|
txb[0] = SI8900_CNFG_0 | SI8900_CNFG_0_PGA | SI8900_CNFG_0_MODE;
|
|
} else if (i == 1) {
|
|
txb[0] = SI8900_CNFG_0 | SI8900_CNFG_0_PGA | SI8900_CNFG_0_MODE | SI8900_CNFG_0_MX0;
|
|
} else {
|
|
txb[0] = SI8900_CNFG_0 | SI8900_CNFG_0_PGA | SI8900_CNFG_0_MODE | SI8900_CNFG_0_MX1;
|
|
}
|
|
|
|
tx_len = 1;
|
|
|
|
for (int j = 0;j < 4;j++) {
|
|
sdWriteTimeout(&HW_SI8900_DEV, txb, tx_len, MS2ST(10));
|
|
rx_len = 1;
|
|
size_t res = sdReadTimeout(&HW_SI8900_DEV, rxb, rx_len, 5);
|
|
if (res == rx_len && rxb[0] == txb[0]) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
rx_len = 2;
|
|
size_t res = sdReadTimeout(&HW_SI8900_DEV, rxb, rx_len, MS2ST(10));
|
|
if (res == rx_len) {
|
|
m_voltages[i] = (float)((((uint16_t)rxb[0] & 0b00001111) << 6) |
|
|
(((uint16_t)rxb[1] >> 1) & 0b00111111)) / 1023.0 * 3.3;
|
|
}
|
|
}
|
|
|
|
chThdSleepMilliseconds(20);
|
|
while(sdGetTimeout(&HW_SI8900_DEV, TIME_IMMEDIATE) != MSG_TIMEOUT){
|
|
chThdSleepMilliseconds(1);
|
|
};
|
|
}
|
|
}
|
|
|
|
#endif
|