forked from vedderb/bldc
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8503444
commit 5d9cc77
Showing
10 changed files
with
932 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,301 @@ | ||
/* | ||
Copyright 2016 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 "hw.h" | ||
#ifdef HW_HAS_DRV8320 | ||
|
||
#include "drv8320.h" | ||
#include "ch.h" | ||
#include "hal.h" | ||
#include "stm32f4xx_conf.h" | ||
#include "utils.h" | ||
#include <string.h> | ||
|
||
// Private functions | ||
static uint16_t spi_exchange(uint16_t x); | ||
static void spi_transfer(uint16_t *in_buf, const uint16_t *out_buf, int length); | ||
static void spi_begin(void); | ||
static void spi_end(void); | ||
static void spi_delay(void); | ||
|
||
// Private variables | ||
static char m_fault_print_buffer[120]; | ||
|
||
void drv8320_init(void) { | ||
// DRV8320 SPI | ||
palSetPadMode(DRV8320_MISO_GPIO, DRV8320_MISO_PIN, PAL_MODE_INPUT_PULLUP); | ||
palSetPadMode(DRV8320_SCK_GPIO, DRV8320_SCK_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); | ||
palSetPadMode(DRV8320_CS_GPIO, DRV8320_CS_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); | ||
palSetPadMode(DRV8320_MOSI_GPIO, DRV8320_MOSI_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); | ||
palSetPad(DRV8320_MOSI_GPIO, DRV8320_MOSI_PIN); | ||
|
||
chThdSleepMilliseconds(100); | ||
|
||
// Disable OC | ||
drv8320_write_reg(5, 0x04C0); | ||
drv8320_write_reg(5, 0x04C0); | ||
} | ||
|
||
/** | ||
* Set the threshold of the over current protection of the DRV8320. It works by measuring | ||
* the voltage drop across drain-source of the MOSFETs and activates when it is higher than | ||
* a set value. Notice that this current limit is not very accurate. | ||
* | ||
* @param val | ||
* The value to use. Range [0 15]. A lower value corresponds to a lower current limit. See | ||
* the drv8320 datasheet for how to convert these values to currents. | ||
*/ | ||
void drv8320_set_oc_adj(int val) { | ||
int reg = drv8320_read_reg(5); | ||
reg &= 0x000F; | ||
reg |= (val & 0xF); | ||
//drv8320_write_reg(5, reg); | ||
} | ||
|
||
/** | ||
* Set the over current protection mode of the DRV8320. | ||
* | ||
* @param mode | ||
* The over current protection mode. | ||
*/ | ||
void drv8320_set_oc_mode(drv8301_oc_mode mode) { | ||
int reg = drv8320_read_reg(5); | ||
reg &= 0xFF3F; | ||
reg |= (mode & 0x03) << 6; | ||
//drv8320_write_reg(5, reg); | ||
} | ||
|
||
/** | ||
* Read the fault codes of the DRV8320. | ||
* | ||
* @return | ||
* The fault codes, where the bits represent the following: | ||
* b0: FETLC_OC | ||
* b1: FETHC_OC | ||
* b2: FETLB_OC | ||
* b3: FETHB_OC | ||
* b4: FETLA_OC | ||
* b5: FETHA_OC | ||
* b6: OTW | ||
* b7: OTSD | ||
* b8: PVDD_UV | ||
* b9: GVDD_UV | ||
* b10: FAULT | ||
* b11: GVDD_OV | ||
* | ||
*/ | ||
unsigned long drv8320_read_faults(void) { | ||
unsigned long r0 = drv8320_read_reg(0); | ||
int r1 = drv8320_read_reg(1); | ||
return r0 | (r1 << 16); | ||
} | ||
|
||
/** | ||
* Reset all latched faults. | ||
*/ | ||
void drv8320_reset_faults(void) { | ||
int reg = drv8320_read_reg(2); | ||
reg |= 1; | ||
drv8320_write_reg(2, reg); | ||
} | ||
|
||
char* drv8320_faults_to_string(unsigned long faults) { | ||
if (faults == 0) { | ||
strcpy(m_fault_print_buffer, "No DRV8320 faults"); | ||
} else { | ||
strcpy(m_fault_print_buffer, "|"); | ||
|
||
if (faults & DRV8320_FAULT_FET_LC_OC) { | ||
strcat(m_fault_print_buffer, " FETLC_OC |"); | ||
} | ||
|
||
if (faults & DRV8320_FAULT_FET_HC_OC) { | ||
strcat(m_fault_print_buffer, " FETHC_OC |"); | ||
} | ||
|
||
if (faults & DRV8320_FAULT_FET_LB_OC) { | ||
strcat(m_fault_print_buffer, " FETLB_OC |"); | ||
} | ||
|
||
if (faults & DRV8320_FAULT_FET_HB_OC) { | ||
strcat(m_fault_print_buffer, " FETHB_OC |"); | ||
} | ||
|
||
if (faults & DRV8320_FAULT_FET_LA_OC) { | ||
strcat(m_fault_print_buffer, " FETLA_OC |"); | ||
} | ||
|
||
if (faults & DRV8320_FAULT_FET_HA_OC) { | ||
strcat(m_fault_print_buffer, " FETHA_OC |"); | ||
} | ||
|
||
if (faults & DRV8320_FAULT_OTSD) { | ||
strcat(m_fault_print_buffer, " OTSD |"); | ||
} | ||
|
||
if (faults & DRV8320_FAULT_UVLO) { | ||
strcat(m_fault_print_buffer, " UVLO |"); | ||
} | ||
|
||
if (faults & DRV8320_FAULT_GDF) { | ||
strcat(m_fault_print_buffer, " GDF |"); | ||
} | ||
|
||
if (faults & DRV8320_FAULT_VDS_OCP) { | ||
strcat(m_fault_print_buffer, " VDS OCP |"); | ||
} | ||
|
||
if (faults & DRV8320_FAULT_FAULT) { | ||
strcat(m_fault_print_buffer, " FAULT |"); | ||
} | ||
|
||
if (faults & DRV8320_FAULT_VGS_LC) { | ||
strcat(m_fault_print_buffer, " FETLC VGS |"); | ||
} | ||
|
||
if (faults & DRV8320_FAULT_VGS_HC) { | ||
strcat(m_fault_print_buffer, " FETHC VGS |"); | ||
} | ||
|
||
if (faults & DRV8320_FAULT_VGS_LB) { | ||
strcat(m_fault_print_buffer, " FETLB VGS |"); | ||
} | ||
|
||
if (faults & DRV8320_FAULT_VGS_HB) { | ||
strcat(m_fault_print_buffer, " FETHB VGS |"); | ||
} | ||
|
||
if (faults & DRV8320_FAULT_VGS_LA) { | ||
strcat(m_fault_print_buffer, " FETLA VGS |"); | ||
} | ||
|
||
if (faults & DRV8320_FAULT_VGS_HA) { | ||
strcat(m_fault_print_buffer, " FETHA VGS |"); | ||
} | ||
|
||
if (faults & DRV8320_FAULT_CPUV) { | ||
strcat(m_fault_print_buffer, " CPU V |"); | ||
} | ||
|
||
if (faults & DRV8320_FAULT_OTW) { | ||
strcat(m_fault_print_buffer, " OTW |"); | ||
} | ||
|
||
if (faults & DRV8320_FAULT_SC_OC) { | ||
strcat(m_fault_print_buffer, " AMP C OC |"); | ||
} | ||
|
||
if (faults & DRV8320_FAULT_SB_OC) { | ||
strcat(m_fault_print_buffer, " AMP B OC |"); | ||
} | ||
|
||
if (faults & DRV8320_FAULT_SA_OC) { | ||
strcat(m_fault_print_buffer, " AMP A OC |"); | ||
} | ||
} | ||
|
||
return m_fault_print_buffer; | ||
} | ||
|
||
unsigned int drv8320_read_reg(int reg) { | ||
uint16_t out = 0; | ||
out |= (1 << 15); | ||
out |= (reg & 0x0F) << 11; | ||
out |= 0x807F; | ||
|
||
if (reg != 0) { | ||
spi_begin(); | ||
spi_exchange(out); | ||
spi_end(); | ||
} | ||
|
||
spi_begin(); | ||
uint16_t res = spi_exchange(out); | ||
spi_end(); | ||
|
||
return res; | ||
} | ||
|
||
void drv8320_write_reg(int reg, int data) { | ||
uint16_t out = 0; | ||
out |= (reg & 0x0F) << 11; | ||
out |= data & 0x7FF; | ||
|
||
spi_begin(); | ||
spi_exchange(out); | ||
spi_end(); | ||
} | ||
|
||
// Software SPI | ||
static uint16_t spi_exchange(uint16_t x) { | ||
uint16_t rx; | ||
spi_transfer(&rx, &x, 1); | ||
return rx; | ||
} | ||
|
||
static void spi_transfer(uint16_t *in_buf, const uint16_t *out_buf, int length) { | ||
for (int i = 0;i < length;i++) { | ||
uint16_t send = out_buf ? out_buf[i] : 0xFFFF; | ||
uint16_t receive = 0; | ||
|
||
for (int bit = 0;bit < 16;bit++) { | ||
palWritePad(DRV8320_MOSI_GPIO, DRV8320_MOSI_PIN, send >> 15); | ||
send <<= 1; | ||
|
||
palSetPad(DRV8320_SCK_GPIO, DRV8320_SCK_PIN); | ||
spi_delay(); | ||
|
||
palClearPad(DRV8320_SCK_GPIO, DRV8320_SCK_PIN); | ||
|
||
int r1, r2, r3; | ||
r1 = palReadPad(DRV8320_MISO_GPIO, DRV8320_MISO_PIN); | ||
__NOP(); | ||
r2 = palReadPad(DRV8320_MISO_GPIO, DRV8320_MISO_PIN); | ||
__NOP(); | ||
r3 = palReadPad(DRV8320_MISO_GPIO, DRV8320_MISO_PIN); | ||
|
||
receive <<= 1; | ||
if (utils_middle_of_3_int(r1, r2, r3)) { | ||
receive |= 1; | ||
} | ||
|
||
spi_delay(); | ||
} | ||
|
||
if (in_buf) { | ||
in_buf[i] = receive; | ||
} | ||
} | ||
} | ||
|
||
static void spi_begin(void) { | ||
palClearPad(DRV8320_CS_GPIO, DRV8320_CS_PIN); | ||
} | ||
|
||
static void spi_end(void) { | ||
palSetPad(DRV8320_CS_GPIO, DRV8320_CS_PIN); | ||
} | ||
|
||
static void spi_delay(void) { | ||
for (volatile int i = 0;i < 10;i++) { | ||
__NOP(); | ||
} | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
Copyright 2017 Benjamin Vedder benjamin@vedder.se | ||
This program 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. | ||
This program 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/>. | ||
*/ | ||
|
||
#ifndef HWCONF_DRV8320_H_ | ||
#define HWCONF_DRV8320_H_ | ||
|
||
#include "datatypes.h" | ||
|
||
// Functions | ||
void drv8320_init(void); | ||
void drv8320_set_oc_adj(int val); | ||
void drv8320_set_oc_mode(drv8301_oc_mode mode); | ||
unsigned long drv8320_read_faults(void); | ||
void drv8320_reset_faults(void); | ||
char* drv8320_faults_to_string(unsigned long faults); | ||
unsigned int drv8320_read_reg(int reg); | ||
void drv8320_write_reg(int reg, int data); | ||
|
||
// Defines | ||
#define DRV8320_FAULT_FET_LC_OC (1 << 0) | ||
#define DRV8320_FAULT_FET_HC_OC (1 << 1) | ||
#define DRV8320_FAULT_FET_LB_OC (1 << 2) | ||
#define DRV8320_FAULT_FET_HB_OC (1 << 3) | ||
#define DRV8320_FAULT_FET_LA_OC (1 << 4) | ||
#define DRV8320_FAULT_FET_HA_OC (1 << 5) | ||
#define DRV8320_FAULT_OTSD (1 << 6) | ||
#define DRV8320_FAULT_UVLO (1 << 7) | ||
#define DRV8320_FAULT_GDF (1 << 8) | ||
#define DRV8320_FAULT_VDS_OCP (1 << 9) | ||
#define DRV8320_FAULT_FAULT (1 << 10) | ||
|
||
#define DRV8320_FAULT_VGS_LC (1 << 16) | ||
#define DRV8320_FAULT_VGS_HC (1 << 17) | ||
#define DRV8320_FAULT_VGS_LB (1 << 18) | ||
#define DRV8320_FAULT_VGS_HB (1 << 19) | ||
#define DRV8320_FAULT_VGS_LA (1 << 20) | ||
#define DRV8320_FAULT_VGS_HA (1 << 21) | ||
#define DRV8320_FAULT_CPUV (1 << 22) | ||
#define DRV8320_FAULT_OTW (1 << 23) | ||
#define DRV8320_FAULT_SC_OC (1 << 24) | ||
#define DRV8320_FAULT_SB_OC (1 << 25) | ||
#define DRV8320_FAULT_SA_OC (1 << 26) | ||
|
||
#endif /* HWCONF_DRV8320_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.