try to fix submodule
This commit is contained in:
175
firmware/lib/Arduino-FOC-drivers/src/drivers/drv8316/README.md
Normal file
175
firmware/lib/Arduino-FOC-drivers/src/drivers/drv8316/README.md
Normal file
@@ -0,0 +1,175 @@
|
||||
|
||||
# DRV8316 SimpleFOC driver
|
||||
|
||||
The DRV8316 is a integrated FET, integrated current sensing 3-phase BLDC driver IC from Texas Instruments, including all protections and many cool configuration optons. See https://www.ti.com/product/DRV8316 for more information.
|
||||
|
||||
This driver includes a DRV8316 SPI driver, and specific subclasses for SimpleFOCs BLDCDriver3PWM and BLDCDriver6PWM generic drivers. The code is designed to be "Ardunio compatible" and should work with any of the hardware architectures supported by SimpleFOC.
|
||||
|
||||
## Hardware setup
|
||||
|
||||
To use the DRV8316 you will have to connect the following:
|
||||
|
||||
- GND
|
||||
- SPI MOSI
|
||||
- SPI MISO
|
||||
- SPI CLK
|
||||
- SPI nCS
|
||||
- INH_U - connect to motor PWM pin
|
||||
- INH_V - connect to motor PWM pin
|
||||
- INH_W - connect to motor PWM pin
|
||||
- INL_U - connect to motor PWM pin for 6-PWM, or to digital out (or pull up to VCC) for 3-PWM operation
|
||||
- INL_V - connect to motor PWM pin for 6-PWM, or to digital out (or pull up to VCC) for 3-PWM operation
|
||||
- INL_W - connect to motor PWM pin for 6-PWM, or to digital out (or pull up to VCC) for 3-PWM operation
|
||||
|
||||
Optionally, but probably useful:
|
||||
|
||||
- nFault - digital in, active low
|
||||
- DRVOFF - digital out
|
||||
|
||||
For current sensting:
|
||||
|
||||
- VREF - either connect to DAC output of the MCU or a fixed voltage reference.
|
||||
- ISENA - connect to analog in
|
||||
- ISENB - connect to analog in
|
||||
- ISENC - connect to analog in
|
||||
|
||||
For current limiting:
|
||||
|
||||
- ILIM (same as VREF) - connect it to a DAC output of the MCU if you want to control the current limit from the MCU
|
||||
|
||||
## Usage
|
||||
|
||||
Usage is quite easy, especially if you already know SimpleFOC. See also the [examples](https://github.com/simplefoc/Arduino-FOC-drivers/examples/drivers/drv8316/)
|
||||
|
||||
```c++
|
||||
#include "Arduino.h"
|
||||
#include <Wire.h>
|
||||
#include <SimpleFOC.h>
|
||||
#include <Math.h>
|
||||
#include "SimpleFOCDrivers.h"
|
||||
#include "drivers/drv8316/drv8316.h"
|
||||
|
||||
BLDCMotor motor = BLDCMotor(11);
|
||||
DRV8316Driver6PWM driver = DRV8316Driver6PWM(A3,0,A4,1,2,6,7,false); // MKR1010 6-PWM
|
||||
|
||||
//... normal simpleFOC init code...
|
||||
```
|
||||
|
||||
Or, for 3-PWM:
|
||||
|
||||
```c++
|
||||
#include "Arduino.h"
|
||||
#include <Wire.h>
|
||||
#include <SimpleFOC.h>
|
||||
#include <Math.h>
|
||||
#include "SimpleFOCDrivers.h"
|
||||
#include "drivers/drv8316/drv8316.h"
|
||||
|
||||
BLDCMotor motor = BLDCMotor(11);
|
||||
DRV8316Driver3PWM driver = DRV8316Driver3PWM(A3,A4,2,7,false); // MKR1010 3-PWM
|
||||
// these are examples, for 3-PWM you could use any output pins as the enable pins.
|
||||
#define ENABLE_A 0
|
||||
#define ENABLE_B 1
|
||||
#define ENABLE_C 6
|
||||
|
||||
void setup() {
|
||||
|
||||
|
||||
pinMode(ENABLE_A, OUTPUT);
|
||||
digitalWrite(ENABLE_A, 1); // enable
|
||||
pinMode(ENABLE_B, OUTPUT);
|
||||
digitalWrite(ENABLE_B, 1); // enable
|
||||
pinMode(ENABLE_C, OUTPUT);
|
||||
digitalWrite(ENABLE_C, 1); // enable
|
||||
|
||||
|
||||
//... normal simpleFOC init code...
|
||||
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
You can use the driver's features. In general you can do this at any time, but certain features only make sense at setup-time (e.g. setting the PWM mode, which is handled automatically by the DRV8316Driver3PWM class, or setting the current limit, which you generally want to get done before applying power to the motor).
|
||||
|
||||
Driver usage, for example reading and printing the complete status:
|
||||
|
||||
```c++
|
||||
DRV8316Status status = driver.getStatus();
|
||||
Serial.println("DRV8316 Status:");
|
||||
Serial.print("Fault: ");
|
||||
Serial.println(status.isFault());
|
||||
Serial.print("Buck Error: ");
|
||||
Serial.print(status.isBuckError());
|
||||
Serial.print(" Undervoltage: ");
|
||||
Serial.print(status.isBuckUnderVoltage());
|
||||
Serial.print(" OverCurrent: ");
|
||||
Serial.println(status.isBuckOverCurrent());
|
||||
Serial.print("Charge Pump UnderVoltage: ");
|
||||
Serial.println(status.isChargePumpUnderVoltage());
|
||||
Serial.print("OTP Error: ");
|
||||
Serial.println(status.isOneTimeProgrammingError());
|
||||
Serial.print("OverCurrent: ");
|
||||
Serial.print(status.isOverCurrent());
|
||||
Serial.print(" Ah: ");
|
||||
Serial.print(status.isOverCurrent_Ah());
|
||||
Serial.print(" Al: ");
|
||||
Serial.print(status.isOverCurrent_Al());
|
||||
Serial.print(" Bh: ");
|
||||
Serial.print(status.isOverCurrent_Bh());
|
||||
Serial.print(" Bl: ");
|
||||
Serial.print(status.isOverCurrent_Bl());
|
||||
Serial.print(" Ch: ");
|
||||
Serial.print(status.isOverCurrent_Ch());
|
||||
Serial.print(" Cl: ");
|
||||
Serial.println(status.isOverCurrent_Cl());
|
||||
Serial.print("OverTemperature: ");
|
||||
Serial.print(status.isOverTemperature());
|
||||
Serial.print(" Shutdown: ");
|
||||
Serial.print(status.isOverTemperatureShutdown());
|
||||
Serial.print(" Warning: ");
|
||||
Serial.println(status.isOverTemperatureWarning());
|
||||
Serial.print("OverVoltage: ");
|
||||
Serial.println(status.isOverVoltage());
|
||||
Serial.print("PowerOnReset: ");
|
||||
Serial.println(status.isPowerOnReset());
|
||||
Serial.print("SPI Error: ");
|
||||
Serial.print(status.isSPIError());
|
||||
Serial.print(" Address: ");
|
||||
Serial.print(status.isSPIAddressError());
|
||||
Serial.print(" Clock: ");
|
||||
Serial.print(status.isSPIClockFramingError());
|
||||
Serial.print(" Parity: ");
|
||||
Serial.println(status.isSPIParityError());
|
||||
if (status.isFault())
|
||||
driver.clearFault();
|
||||
delayMicroseconds(1); // ensure 400ns delay
|
||||
DRV8316_PWMMode val = driver.getPWMMode();
|
||||
Serial.print("PWM Mode: ");
|
||||
Serial.println(val);
|
||||
delayMicroseconds(1); // ensure 400ns delay
|
||||
bool lock = driver.isRegistersLocked();
|
||||
Serial.print("Lock: ");
|
||||
Serial.println(lock);
|
||||
```
|
||||
|
||||
|
||||
Setting options can be conveniently done via the provided setter methods. All documented registers and options are available via the driver, and the option values can be accessed via enums.
|
||||
|
||||
Leave at least 400ns delay between reading and/or writing options to ensure you don't talk to the DRV8316 too quickly:
|
||||
|
||||
```c++
|
||||
driver.setPWM100Frequency(DRV8316_PWM100DUTY::FREQ_40KHz);
|
||||
delayMicroseconds(1); // ensure 400ns delay
|
||||
driver.setBuckVoltage(DRV8316_BuckVoltage::VB_5V7);
|
||||
```
|
||||
|
||||
|
||||
### Current sensing
|
||||
|
||||
TODO...
|
||||
|
||||
### Current limiting
|
||||
|
||||
TODO...
|
||||
|
||||
586
firmware/lib/Arduino-FOC-drivers/src/drivers/drv8316/drv8316.cpp
Normal file
586
firmware/lib/Arduino-FOC-drivers/src/drivers/drv8316/drv8316.cpp
Normal file
@@ -0,0 +1,586 @@
|
||||
|
||||
|
||||
#include "./drv8316.h"
|
||||
|
||||
|
||||
void DRV8316Driver3PWM::init(SPIClass* _spi) {
|
||||
DRV8316Driver::init(_spi);
|
||||
setRegistersLocked(false);
|
||||
delayMicroseconds(1);
|
||||
DRV8316Driver::setPWMMode(DRV8316_PWMMode::PWM3_Mode);
|
||||
BLDCDriver3PWM::init();
|
||||
};
|
||||
|
||||
|
||||
void DRV8316Driver6PWM::init(SPIClass* _spi) {
|
||||
DRV8316Driver::init(_spi);
|
||||
setRegistersLocked(false);
|
||||
delayMicroseconds(1);
|
||||
DRV8316Driver::setPWMMode(DRV8316_PWMMode::PWM6_Mode); // default mode is 6-PWM
|
||||
BLDCDriver6PWM::init();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* SPI setup:
|
||||
*
|
||||
* capture on falling, propagate on rising =
|
||||
* MSB first
|
||||
*
|
||||
* 16 bit words
|
||||
* outgoing: R/W:1 addr:6 parity:1 data:8
|
||||
* incoming: status:8 data:8
|
||||
*
|
||||
* on reads, incoming data is content of register being read
|
||||
* on writes, incomnig data is content of register being written
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
void handleInterrupt() {
|
||||
|
||||
}
|
||||
|
||||
void DRV8316Driver::init(SPIClass* _spi) {
|
||||
// TODO make SPI speed configurable
|
||||
spi = _spi;
|
||||
settings = SPISettings(1000000, MSBFIRST, SPI_MODE1);
|
||||
|
||||
//setup pins
|
||||
pinMode(cs, OUTPUT);
|
||||
digitalWrite(cs, HIGH); // switch off
|
||||
|
||||
//SPI has an internal SPI-device counter, it is possible to call "begin()" from different devices
|
||||
spi->begin();
|
||||
|
||||
if (_isset(nFault)) {
|
||||
pinMode(nFault, INPUT);
|
||||
// TODO add interrupt handler on the nFault pin if configured
|
||||
// add configuration for how to handle faults... idea: interrupt handler calls a callback, depending on the type of fault
|
||||
// consider what would be a useful configuration in practice? What do we want to do on a fault, e.g. over-temperature for example?
|
||||
|
||||
//attachInterrupt(digitalPinToInterrupt(nFault), handleInterrupt, PinStatus::FALLING);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
bool DRV8316Driver::getParity(uint16_t data) {
|
||||
//PARITY = XNOR(CMD, A5..A0, D7..D0)
|
||||
uint8_t par = 0;
|
||||
for (int i=0;i<16;i++) {
|
||||
if (((data)>>i) & 0x0001)
|
||||
par+=1;
|
||||
}
|
||||
return (par&0x01)==0x01; // even number of bits means true
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
uint16_t DRV8316Driver::readSPI(uint8_t addr) {
|
||||
digitalWrite(cs, 0);
|
||||
spi->beginTransaction(settings);
|
||||
uint16_t data = (((addr<<1) | 0x80)<<8)|0x0000;
|
||||
if (getParity(data))
|
||||
data |= 0x0100;
|
||||
uint16_t result = spi->transfer16(data);
|
||||
spi->endTransaction();
|
||||
digitalWrite(cs, 1);
|
||||
// Serial.print("SPI Read Result: ");
|
||||
// Serial.print(data, HEX);
|
||||
// Serial.print(" -> ");
|
||||
// Serial.println(result, HEX);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
uint16_t DRV8316Driver::writeSPI(uint8_t addr, uint8_t value) {
|
||||
digitalWrite(cs, 0);
|
||||
spi->beginTransaction(settings);
|
||||
uint16_t data = ((addr<<1)<<8)|value;
|
||||
if (getParity(data))
|
||||
data |= 0x0100;
|
||||
uint16_t result = spi->transfer16(data);
|
||||
spi->endTransaction();
|
||||
digitalWrite(cs, 1);
|
||||
// Serial.print("SPI Write Result: ");
|
||||
// Serial.print(data, HEX);
|
||||
// Serial.print(" -> ");
|
||||
// Serial.println(result, HEX);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DRV8316Status DRV8316Driver::getStatus() {
|
||||
IC_Status data;
|
||||
Status__1 data1;
|
||||
Status__2 data2;
|
||||
uint16_t result = readSPI(IC_Status_ADDR);
|
||||
data.reg = (result & 0x00FF);
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = readSPI(Status__1_ADDR);
|
||||
data1.reg = (result & 0x00FF);
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = readSPI(Status__2_ADDR);
|
||||
data2.reg = (result & 0x00FF);
|
||||
return DRV8316Status(data, data1, data2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void DRV8316Driver::clearFault() {
|
||||
uint16_t result = readSPI(Control__2_ADDR);
|
||||
Control__2 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.CLR_FLT |= 1;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__2_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool DRV8316Driver::isRegistersLocked(){
|
||||
uint16_t result = readSPI(Control__1_ADDR);
|
||||
Control__1 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return data.REG_LOCK==REG_LOCK_LOCK;
|
||||
}
|
||||
void DRV8316Driver::setRegistersLocked(bool lock){
|
||||
uint16_t result = readSPI(Control__1_ADDR);
|
||||
Control__1 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.REG_LOCK = lock?REG_LOCK_LOCK:REG_LOCK_UNLOCK;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__1_ADDR, data.reg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
DRV8316_PWMMode DRV8316Driver::getPWMMode() {
|
||||
uint16_t result = readSPI(Control__2_ADDR);
|
||||
Control__2 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return (DRV8316_PWMMode)data.PWM_MODE;
|
||||
};
|
||||
void DRV8316Driver::setPWMMode(DRV8316_PWMMode pwmMode){
|
||||
uint16_t result = readSPI(Control__2_ADDR);
|
||||
Control__2 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.PWM_MODE = pwmMode;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__2_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
DRV8316_Slew DRV8316Driver::getSlew() {
|
||||
uint16_t result = readSPI(Control__2_ADDR);
|
||||
Control__2 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return (DRV8316_Slew)data.SLEW;
|
||||
};
|
||||
void DRV8316Driver::setSlew(DRV8316_Slew slewRate) {
|
||||
uint16_t result = readSPI(Control__2_ADDR);
|
||||
Control__2 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.SLEW = slewRate;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__2_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
DRV8316_SDOMode DRV8316Driver::getSDOMode() {
|
||||
uint16_t result = readSPI(Control__2_ADDR);
|
||||
Control__2 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return (DRV8316_SDOMode)data.SDO_MODE;
|
||||
};
|
||||
void DRV8316Driver::setSDOMode(DRV8316_SDOMode sdoMode) {
|
||||
uint16_t result = readSPI(Control__2_ADDR);
|
||||
Control__2 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.SDO_MODE = sdoMode;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__2_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool DRV8316Driver::isOvertemperatureReporting(){
|
||||
uint16_t result = readSPI(Control__3_ADDR);
|
||||
Control__3 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return data.OTW_REP==OTW_REP_ENABLE;
|
||||
};
|
||||
void DRV8316Driver::setOvertemperatureReporting(bool reportFault){
|
||||
uint16_t result = readSPI(Control__3_ADDR);
|
||||
Control__3 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.OTW_REP = reportFault?OTW_REP_ENABLE:OTW_REP_DISABLE;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__3_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool DRV8316Driver::isSPIFaultReporting(){
|
||||
uint16_t result = readSPI(Control__3_ADDR);
|
||||
Control__3 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return data.SPI_FLT_REP==SPI_FLT_REP_ENABLE;
|
||||
}
|
||||
void DRV8316Driver::setSPIFaultReporting(bool reportFault){
|
||||
uint16_t result = readSPI(Control__3_ADDR);
|
||||
Control__3 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.SPI_FLT_REP = reportFault?SPI_FLT_REP_ENABLE:SPI_FLT_REP_DISABLE;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__3_ADDR, data.reg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool DRV8316Driver::isOvervoltageProtection(){
|
||||
uint16_t result = readSPI(Control__3_ADDR);
|
||||
Control__3 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return data.OVP_EN==OVP_EN_ENABLE;
|
||||
};
|
||||
void DRV8316Driver::setOvervoltageProtection(bool enabled){
|
||||
uint16_t result = readSPI(Control__3_ADDR);
|
||||
Control__3 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.OVP_EN = enabled?OVP_EN_ENABLE:OVP_EN_DISABLE;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__3_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
DRV8316_OVP DRV8316Driver::getOvervoltageLevel(){
|
||||
uint16_t result = readSPI(Control__3_ADDR);
|
||||
Control__3 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return (DRV8316_OVP)data.OVP_SEL;
|
||||
};
|
||||
void DRV8316Driver::setOvervoltageLevel(DRV8316_OVP voltage){
|
||||
uint16_t result = readSPI(Control__3_ADDR);
|
||||
Control__3 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.OVP_SEL = voltage;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__3_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
DRV8316_PWM100DUTY DRV8316Driver::getPWM100Frequency(){
|
||||
uint16_t result = readSPI(Control__3_ADDR);
|
||||
Control__3 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return (DRV8316_PWM100DUTY)data.PWM_100_DUTY_SEL;
|
||||
};
|
||||
void DRV8316Driver::setPWM100Frequency(DRV8316_PWM100DUTY freq){
|
||||
uint16_t result = readSPI(Control__3_ADDR);
|
||||
Control__3 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.PWM_100_DUTY_SEL = freq;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__3_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
DRV8316_OCPMode DRV8316Driver::getOCPMode(){
|
||||
uint16_t result = readSPI(Control__4_ADDR);
|
||||
Control__4 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return (DRV8316_OCPMode)data.OCP_MODE;
|
||||
|
||||
};
|
||||
void DRV8316Driver::setOCPMode(DRV8316_OCPMode ocpMode){
|
||||
uint16_t result = readSPI(Control__4_ADDR);
|
||||
Control__4 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.OCP_MODE = ocpMode;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__4_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
DRV8316_OCPLevel DRV8316Driver::getOCPLevel(){
|
||||
uint16_t result = readSPI(Control__4_ADDR);
|
||||
Control__4 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return (DRV8316_OCPLevel)data.OCP_LVL;
|
||||
};
|
||||
void DRV8316Driver::setOCPLevel(DRV8316_OCPLevel amps){
|
||||
uint16_t result = readSPI(Control__4_ADDR);
|
||||
Control__4 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.OCP_LVL = amps;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__4_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
DRV8316_OCPRetry DRV8316Driver::getOCPRetryTime(){
|
||||
uint16_t result = readSPI(Control__4_ADDR);
|
||||
Control__4 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return (DRV8316_OCPRetry)data.OCP_RETRY;
|
||||
};
|
||||
void DRV8316Driver::setOCPRetryTime(DRV8316_OCPRetry ms){
|
||||
uint16_t result = readSPI(Control__4_ADDR);
|
||||
Control__4 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.OCP_RETRY = ms;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__4_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
DRV8316_OCPDeglitch DRV8316Driver::getOCPDeglitchTime(){
|
||||
uint16_t result = readSPI(Control__4_ADDR);
|
||||
Control__4 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return (DRV8316_OCPDeglitch)data.OCP_DEG;
|
||||
};
|
||||
void DRV8316Driver::setOCPDeglitchTime(DRV8316_OCPDeglitch ms){
|
||||
uint16_t result = readSPI(Control__4_ADDR);
|
||||
Control__4 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.OCP_DEG = ms;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__4_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool DRV8316Driver::isOCPClearInPWMCycleChange(){
|
||||
uint16_t result = readSPI(Control__4_ADDR);
|
||||
Control__4 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return data.OCP_CBC==OCP_CBC_ENABLE;
|
||||
};
|
||||
void DRV8316Driver::setOCPClearInPWMCycleChange(bool enable){
|
||||
uint16_t result = readSPI(Control__4_ADDR);
|
||||
Control__4 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.OCP_CBC = enable?OCP_CBC_ENABLE:OCP_CBC_DISABLE;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__4_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool DRV8316Driver::isDriverOffEnabled(){
|
||||
uint16_t result = readSPI(Control__4_ADDR);
|
||||
Control__4 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return data.DRV_OFF==DRV_OFF_ENABLE;
|
||||
};
|
||||
void DRV8316Driver::setDriverOffEnabled(bool enabled){
|
||||
uint16_t result = readSPI(Control__4_ADDR);
|
||||
Control__4 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.DRV_OFF = enabled?DRV_OFF_ENABLE:DRV_OFF_DISABLE;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__4_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
DRV8316_CSAGain DRV8316Driver::getCurrentSenseGain(){
|
||||
uint16_t result = readSPI(Control__5_ADDR);
|
||||
Control__5 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return (DRV8316_CSAGain)data.CSA_GAIN;
|
||||
};
|
||||
void DRV8316Driver::setCurrentSenseGain(DRV8316_CSAGain gain){
|
||||
uint16_t result = readSPI(Control__5_ADDR);
|
||||
Control__5 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.CSA_GAIN = gain;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__5_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool DRV8316Driver::isActiveSynchronousRectificationEnabled(){
|
||||
uint16_t result = readSPI(Control__5_ADDR);
|
||||
Control__5 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return data.EN_ASR==EN_ASR_ENABLE;
|
||||
|
||||
};
|
||||
void DRV8316Driver::setActiveSynchronousRectificationEnabled(bool enabled){
|
||||
uint16_t result = readSPI(Control__5_ADDR);
|
||||
Control__5 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.EN_ASR = enabled?EN_ASR_ENABLE:EN_ASR_DISABLE;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__5_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool DRV8316Driver::isActiveAsynchronousRectificationEnabled(){
|
||||
uint16_t result = readSPI(Control__5_ADDR);
|
||||
Control__5 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return data.EN_AAR==EN_AAR_ENABLE;
|
||||
};
|
||||
void DRV8316Driver::setActiveAsynchronousRectificationEnabled(bool enabled){
|
||||
uint16_t result = readSPI(Control__5_ADDR);
|
||||
Control__5 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.EN_AAR = enabled?EN_AAR_ENABLE:EN_AAR_DISABLE;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__5_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
DRV8316_Recirculation DRV8316Driver::getRecirculationMode(){
|
||||
uint16_t result = readSPI(Control__5_ADDR);
|
||||
Control__5 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return (DRV8316_Recirculation)data.ILIM_RECIR;
|
||||
};
|
||||
void DRV8316Driver::setRecirculationMode(DRV8316_Recirculation recirculationMode){
|
||||
uint16_t result = readSPI(Control__5_ADDR);
|
||||
Control__5 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.ILIM_RECIR = recirculationMode;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__5_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool DRV8316Driver::isBuckEnabled(){
|
||||
uint16_t result = readSPI(Control__6_ADDR);
|
||||
Control__6 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return data.BUCK_DIS==BUCK_DIS_BUCK_ENABLE;
|
||||
};
|
||||
void DRV8316Driver::setBuckEnabled(bool enabled){
|
||||
uint16_t result = readSPI(Control__6_ADDR);
|
||||
Control__6 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.BUCK_DIS = enabled?BUCK_DIS_BUCK_ENABLE:BUCK_DIS_BUCK_DISABLE;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__6_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
DRV8316_BuckVoltage DRV8316Driver::getBuckVoltage(){
|
||||
uint16_t result = readSPI(Control__6_ADDR);
|
||||
Control__6 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return (DRV8316_BuckVoltage)data.BUCK_SEL;
|
||||
};
|
||||
void DRV8316Driver::setBuckVoltage(DRV8316_BuckVoltage volts){
|
||||
uint16_t result = readSPI(Control__6_ADDR);
|
||||
Control__6 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.BUCK_SEL = volts;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__6_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
DRV8316_BuckCurrentLimit DRV8316Driver::getBuckCurrentLimit(){
|
||||
uint16_t result = readSPI(Control__6_ADDR);
|
||||
Control__6 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return (DRV8316_BuckCurrentLimit)data.BUCK_CL;
|
||||
};
|
||||
void DRV8316Driver::setBuckCurrentLimit(DRV8316_BuckCurrentLimit mamps){
|
||||
uint16_t result = readSPI(Control__6_ADDR);
|
||||
Control__6 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.BUCK_CL = mamps;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__6_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool DRV8316Driver::isBuckPowerSequencingEnabled(){
|
||||
uint16_t result = readSPI(Control__6_ADDR);
|
||||
Control__6 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return data.BUCK_PS_DIS==BUCK_PS_DIS_ENABLE;
|
||||
|
||||
};
|
||||
void DRV8316Driver::setBuckPowerSequencingEnabled(bool enabled){
|
||||
uint16_t result = readSPI(Control__6_ADDR);
|
||||
Control__6 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.BUCK_PS_DIS = enabled?BUCK_PS_DIS_ENABLE:BUCK_PS_DIS_DISABLE;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__6_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
DRV8316_DelayTarget DRV8316Driver::getDelayTarget(){
|
||||
uint16_t result = readSPI(Control__10_ADDR);
|
||||
Control__10 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return (DRV8316_DelayTarget)data.DLY_TARGET;
|
||||
};
|
||||
void DRV8316Driver::setDelayTarget(DRV8316_DelayTarget us){
|
||||
uint16_t result = readSPI(Control__10_ADDR);
|
||||
Control__10 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.DLY_TARGET = us;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__10_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool DRV8316Driver::isDelayCompensationEnabled(){
|
||||
uint16_t result = readSPI(Control__10_ADDR);
|
||||
Control__10 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
return data.DLYCMP_EN==DLYCMP_EN_ENABLE;
|
||||
};
|
||||
void DRV8316Driver::setDelayCompensationEnabled(bool enabled){
|
||||
uint16_t result = readSPI(Control__10_ADDR);
|
||||
Control__10 data;
|
||||
data.reg = (result & 0x00FF);
|
||||
data.DLYCMP_EN = enabled?DLYCMP_EN_ENABLE:DLYCMP_EN_DISABLE;
|
||||
delayMicroseconds(1); // delay at least 400ns between operations
|
||||
result = writeSPI(Control__10_ADDR, data.reg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
316
firmware/lib/Arduino-FOC-drivers/src/drivers/drv8316/drv8316.h
Normal file
316
firmware/lib/Arduino-FOC-drivers/src/drivers/drv8316/drv8316.h
Normal file
@@ -0,0 +1,316 @@
|
||||
|
||||
|
||||
#ifndef SIMPLEFOC_DRV8316
|
||||
#define SIMPLEFOC_DRV8316
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <SPI.h>
|
||||
#include <drivers/BLDCDriver3PWM.h>
|
||||
#include <drivers/BLDCDriver6PWM.h>
|
||||
|
||||
#include "./drv8316_registers.h"
|
||||
|
||||
|
||||
enum DRV8316_PWMMode {
|
||||
PWM6_Mode = 0b00,
|
||||
PWM6_CurrentLimit_Mode = 0b01,
|
||||
PWM3_Mode = 0b10,
|
||||
PWM3_CurrentLimit_Mode = 0b11
|
||||
};
|
||||
|
||||
|
||||
enum DRV8316_SDOMode {
|
||||
SDOMode_OpenDrain = 0b0,
|
||||
SDOMode_PushPull = 0b1
|
||||
};
|
||||
|
||||
|
||||
enum DRV8316_Slew {
|
||||
Slew_25Vus = 0b00,
|
||||
Slew_50Vus = 0b01,
|
||||
Slew_150Vus = 0b10,
|
||||
Slew_200Vus = 0b11
|
||||
};
|
||||
|
||||
|
||||
enum DRV8316_OVP {
|
||||
OVP_SEL_32V = 0b0,
|
||||
OVP_SEL_20V = 0b1
|
||||
};
|
||||
|
||||
|
||||
enum DRV8316_PWM100DUTY {
|
||||
FREQ_20KHz = 0b0,
|
||||
FREQ_40KHz = 0b1
|
||||
};
|
||||
|
||||
|
||||
enum DRV8316_OCPMode {
|
||||
Latched_Fault = 0b00,
|
||||
AutoRetry_Fault = 0b01,
|
||||
ReportOnly = 0b10,
|
||||
NoAction = 0b11
|
||||
};
|
||||
|
||||
|
||||
enum DRV8316_OCPLevel {
|
||||
Curr_16A = 0b0,
|
||||
Curr_24A = 0b1
|
||||
};
|
||||
|
||||
|
||||
enum DRV8316_OCPRetry {
|
||||
Retry5ms = 0b0,
|
||||
Retry500ms = 0b1
|
||||
};
|
||||
|
||||
|
||||
enum DRV8316_OCPDeglitch {
|
||||
Deglitch_0us2 = 0b00,
|
||||
Deglitch_0us6 = 0b01,
|
||||
Deglitch_1us1 = 0b10,
|
||||
Deglitch_1us6 = 0b11
|
||||
};
|
||||
|
||||
|
||||
enum DRV8316_CSAGain {
|
||||
Gain_0V15 = 0b00,
|
||||
Gain_0V1875 = 0b01,
|
||||
Gain_0V25 = 0b10,
|
||||
Gain_0V375 = 0b11
|
||||
};
|
||||
|
||||
|
||||
enum DRV8316_Recirculation {
|
||||
BrakeMode = 0b00, // FETs
|
||||
CoastMode = 0b01 // Diodes
|
||||
};
|
||||
|
||||
|
||||
enum DRV8316_BuckVoltage {
|
||||
VB_3V3 = 0b00,
|
||||
VB_5V = 0b01,
|
||||
VB_4V = 0b10,
|
||||
VB_5V7 = 0b11
|
||||
};
|
||||
|
||||
|
||||
enum DRV8316_BuckCurrentLimit {
|
||||
Limit_600mA = 0b00,
|
||||
Limit_150mA = 0b01
|
||||
};
|
||||
|
||||
|
||||
enum DRV8316_DelayTarget {
|
||||
Delay_0us = 0x0,
|
||||
Delay_0us4 = 0x1,
|
||||
Delay_0us6 = 0x2,
|
||||
Delay_0us8 = 0x3,
|
||||
Delay_1us = 0x4,
|
||||
Delay_1us2 = 0x5,
|
||||
Delay_1us4 = 0x6,
|
||||
Delay_1us6 = 0x7,
|
||||
Delay_1us8 = 0x8,
|
||||
Delay_2us = 0x9,
|
||||
Delay_2us2 = 0xA,
|
||||
Delay_2us4 = 0xB,
|
||||
Delay_2us6 = 0xC,
|
||||
Delay_2us8 = 0xD,
|
||||
Delay_3us = 0xE,
|
||||
Delay_3us2 = 0xF
|
||||
};
|
||||
|
||||
|
||||
|
||||
class DRV8316ICStatus {
|
||||
public:
|
||||
DRV8316ICStatus(IC_Status status) : status(status) {};
|
||||
~DRV8316ICStatus() {};
|
||||
|
||||
bool isFault() { return status.FAULT==0b1; };
|
||||
bool isOverTemperature() { return status.OT==0b1; };
|
||||
bool isOverCurrent() { return status.OCP==0b1; };
|
||||
bool isOverVoltage() { return status.OVP==0b1; };
|
||||
bool isSPIError() { return status.SPI_FLT==0b1; };
|
||||
bool isBuckError() { return status.BK_FLT==0b1; };
|
||||
bool isPowerOnReset() { return status.NPOR==0b1; };
|
||||
|
||||
IC_Status status;
|
||||
};
|
||||
|
||||
|
||||
class DRV8316Status1 {
|
||||
public:
|
||||
DRV8316Status1(Status__1 status1) : status1(status1) {};
|
||||
~DRV8316Status1() {};
|
||||
|
||||
|
||||
bool isOverCurrent_Ah() { return status1.OCP_HA==0b1; };
|
||||
bool isOverCurrent_Al() { return status1.OCP_LA==0b1; };
|
||||
bool isOverCurrent_Bh() { return status1.OCP_HB==0b1; };
|
||||
bool isOverCurrent_Bl() { return status1.OCP_LB==0b1; };
|
||||
bool isOverCurrent_Ch() { return status1.OCP_HC==0b1; };
|
||||
bool isOverCurrent_Cl() { return status1.OCP_LC==0b1; };
|
||||
bool isOverTemperatureShutdown() { return status1.OTS==0b1; };
|
||||
bool isOverTemperatureWarning() { return status1.OTW==0b1; };
|
||||
|
||||
Status__1 status1;
|
||||
};
|
||||
|
||||
|
||||
class DRV8316Status2 {
|
||||
public:
|
||||
DRV8316Status2(Status__2 status2) : status2(status2) {};
|
||||
~DRV8316Status2() {};
|
||||
|
||||
|
||||
bool isOneTimeProgrammingError() { return status2.OTP_ERR==0b1; };
|
||||
bool isBuckOverCurrent() { return status2.BUCK_OCP==0b1; };
|
||||
bool isBuckUnderVoltage() { return status2.BUCK_UV==0b1; };
|
||||
bool isChargePumpUnderVoltage() { return status2.VCP_UV==0b1; };
|
||||
bool isSPIParityError() { return status2.SPI_PARITY==0b1; };
|
||||
bool isSPIClockFramingError() { return status2.SPI_SCLK_FLT==0b1; };
|
||||
bool isSPIAddressError() { return status2.SPI_ADDR_FLT==0b1; };
|
||||
|
||||
Status__2 status2;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class DRV8316Status : public DRV8316ICStatus, public DRV8316Status1, public DRV8316Status2 {
|
||||
public:
|
||||
DRV8316Status(IC_Status status, Status__1 status1, Status__2 status2) : DRV8316ICStatus(status), DRV8316Status1(status1), DRV8316Status2(status2) {};
|
||||
~DRV8316Status() {};
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class DRV8316Driver {
|
||||
|
||||
public:
|
||||
DRV8316Driver(int cs, bool currentLimit = false, int nFault = NOT_SET) : currentLimit(currentLimit), cs(cs), nFault(nFault), spi(&SPI), settings(1000000, MSBFIRST, SPI_MODE1) {};
|
||||
virtual ~DRV8316Driver() {};
|
||||
|
||||
virtual void init(SPIClass* _spi = &SPI);
|
||||
|
||||
void clearFault(); // TODO check for fault condition methods
|
||||
|
||||
DRV8316Status getStatus();
|
||||
|
||||
bool isRegistersLocked();
|
||||
void setRegistersLocked(bool lock);
|
||||
|
||||
DRV8316_PWMMode getPWMMode();
|
||||
void setPWMMode(DRV8316_PWMMode pwmMode);
|
||||
|
||||
DRV8316_Slew getSlew();
|
||||
void setSlew(DRV8316_Slew slewRate);
|
||||
|
||||
DRV8316_SDOMode getSDOMode();
|
||||
void setSDOMode(DRV8316_SDOMode sdoMode);
|
||||
|
||||
bool isOvertemperatureReporting();
|
||||
void setOvertemperatureReporting(bool reportFault);
|
||||
|
||||
bool isSPIFaultReporting();
|
||||
void setSPIFaultReporting(bool reportFault);
|
||||
|
||||
bool isOvervoltageProtection();
|
||||
void setOvervoltageProtection(bool enabled);
|
||||
|
||||
DRV8316_OVP getOvervoltageLevel();
|
||||
void setOvervoltageLevel(DRV8316_OVP voltage);
|
||||
|
||||
DRV8316_PWM100DUTY getPWM100Frequency();
|
||||
void setPWM100Frequency(DRV8316_PWM100DUTY freq);
|
||||
|
||||
DRV8316_OCPMode getOCPMode();
|
||||
void setOCPMode(DRV8316_OCPMode ocpMode);
|
||||
|
||||
DRV8316_OCPLevel getOCPLevel();
|
||||
void setOCPLevel(DRV8316_OCPLevel amps);
|
||||
|
||||
DRV8316_OCPRetry getOCPRetryTime();
|
||||
void setOCPRetryTime(DRV8316_OCPRetry ms);
|
||||
|
||||
DRV8316_OCPDeglitch getOCPDeglitchTime();
|
||||
void setOCPDeglitchTime(DRV8316_OCPDeglitch ms);
|
||||
|
||||
bool isOCPClearInPWMCycleChange();
|
||||
void setOCPClearInPWMCycleChange(bool enable);
|
||||
|
||||
bool isDriverOffEnabled();
|
||||
void setDriverOffEnabled(bool enabled);
|
||||
|
||||
DRV8316_CSAGain getCurrentSenseGain();
|
||||
void setCurrentSenseGain(DRV8316_CSAGain gain);
|
||||
|
||||
bool isActiveSynchronousRectificationEnabled();
|
||||
void setActiveSynchronousRectificationEnabled(bool enabled);
|
||||
|
||||
bool isActiveAsynchronousRectificationEnabled();
|
||||
void setActiveAsynchronousRectificationEnabled(bool enabled);
|
||||
|
||||
DRV8316_Recirculation getRecirculationMode();
|
||||
void setRecirculationMode(DRV8316_Recirculation recirculationMode);
|
||||
|
||||
bool isBuckEnabled();
|
||||
void setBuckEnabled(bool enabled);
|
||||
|
||||
DRV8316_BuckVoltage getBuckVoltage();
|
||||
void setBuckVoltage(DRV8316_BuckVoltage volts);
|
||||
|
||||
DRV8316_BuckCurrentLimit getBuckCurrentLimit();
|
||||
void setBuckCurrentLimit(DRV8316_BuckCurrentLimit mamps);
|
||||
|
||||
bool isBuckPowerSequencingEnabled();
|
||||
void setBuckPowerSequencingEnabled(bool enabled);
|
||||
|
||||
DRV8316_DelayTarget getDelayTarget();
|
||||
void setDelayTarget(DRV8316_DelayTarget us);
|
||||
|
||||
bool isDelayCompensationEnabled();
|
||||
void setDelayCompensationEnabled(bool enabled);
|
||||
|
||||
private:
|
||||
uint16_t readSPI(uint8_t addr);
|
||||
uint16_t writeSPI(uint8_t addr, uint8_t data);
|
||||
bool getParity(uint16_t data);
|
||||
|
||||
bool currentLimit;
|
||||
int cs;
|
||||
int nFault;
|
||||
SPIClass* spi;
|
||||
SPISettings settings;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class DRV8316Driver3PWM : public DRV8316Driver, public BLDCDriver3PWM {
|
||||
|
||||
public:
|
||||
DRV8316Driver3PWM(int phA,int phB,int phC, int cs, bool currentLimit = false, int en = NOT_SET, int nFault = NOT_SET) :
|
||||
DRV8316Driver(cs, currentLimit, nFault), BLDCDriver3PWM(phA, phB, phC, en) { enable_active_high=false; };
|
||||
virtual ~DRV8316Driver3PWM() {};
|
||||
|
||||
virtual void init(SPIClass* _spi = &SPI) override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
class DRV8316Driver6PWM : public DRV8316Driver, public BLDCDriver6PWM {
|
||||
|
||||
public:
|
||||
DRV8316Driver6PWM(int phA_h,int phA_l,int phB_h,int phB_l,int phC_h,int phC_l, int cs, bool currentLimit = false, int en = NOT_SET, int nFault = NOT_SET) :
|
||||
DRV8316Driver(cs, currentLimit, nFault), BLDCDriver6PWM(phA_h, phA_l, phB_h, phB_l, phC_h, phC_l, en) { enable_active_high=false; };
|
||||
virtual ~DRV8316Driver6PWM() {};
|
||||
|
||||
virtual void init(SPIClass* _spi = &SPI) override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,184 @@
|
||||
|
||||
|
||||
#ifndef SIMPLEFOC_DRV8316_REGISTERS
|
||||
#define SIMPLEFOC_DRV8316_REGISTERS
|
||||
|
||||
|
||||
#define IC_Status_ADDR 0x0
|
||||
#define Status__1_ADDR 0x1
|
||||
#define Status__2_ADDR 0x2
|
||||
#define Control__1_ADDR 0x3
|
||||
#define Control__2_ADDR 0x4
|
||||
#define Control__3_ADDR 0x5
|
||||
#define Control__4_ADDR 0x6
|
||||
#define Control__5_ADDR 0x7
|
||||
#define Control__6_ADDR 0x8
|
||||
#define Control__10_ADDR 0xC
|
||||
|
||||
#define REG_LOCK_LOCK 0b110
|
||||
#define REG_LOCK_UNLOCK 0b011
|
||||
#define CLR_FAULT_CLR 0b1
|
||||
#define OTW_REP_ENABLE 0b1
|
||||
#define OTW_REP_DISABLE 0b0
|
||||
#define SPI_FLT_REP_ENABLE 0b0
|
||||
#define SPI_FLT_REP_DISABLE 0b1
|
||||
#define OVP_EN_ENABLE 0b1
|
||||
#define OVP_EN_DISABLE 0b0
|
||||
#define OCP_CBC_ENABLE 0b1
|
||||
#define OCP_CBC_DISABLE 0b0
|
||||
#define DRV_OFF_ENABLE 0b1
|
||||
#define DRV_OFF_DISABLE 0b0
|
||||
#define EN_ASR_ENABLE 0b1
|
||||
#define EN_ASR_DISABLE 0b0
|
||||
#define EN_AAR_ENABLE 0b1
|
||||
#define EN_AAR_DISABLE 0b0
|
||||
#define BUCK_DIS_BUCK_DISABLE 0b1
|
||||
#define BUCK_DIS_BUCK_ENABLE 0b0
|
||||
#define BUCK_PS_DIS_DISABLE 0b1
|
||||
#define BUCK_PS_DIS_ENABLE 0b0
|
||||
#define DLYCMP_EN_ENABLE 0b1
|
||||
#define DLYCMP_EN_DISABLE 0b0
|
||||
|
||||
|
||||
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t REG_LOCK:3;
|
||||
uint8_t :5;
|
||||
};
|
||||
uint8_t reg;
|
||||
} Control__1;
|
||||
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t CLR_FLT:1;
|
||||
uint8_t PWM_MODE:2;
|
||||
uint8_t SLEW:2;
|
||||
uint8_t SDO_MODE:1;
|
||||
uint8_t :2;
|
||||
};
|
||||
uint8_t reg;
|
||||
} Control__2;
|
||||
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t OTW_REP:1;
|
||||
uint8_t SPI_FLT_REP:1;
|
||||
uint8_t OVP_EN:1;
|
||||
uint8_t OVP_SEL:1;
|
||||
uint8_t PWM_100_DUTY_SEL:1;
|
||||
uint8_t :3;
|
||||
};
|
||||
uint8_t reg;
|
||||
} Control__3;
|
||||
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t OCP_MODE:2;
|
||||
uint8_t OCP_LVL:1;
|
||||
uint8_t OCP_RETRY:1;
|
||||
uint8_t OCP_DEG:2;
|
||||
uint8_t OCP_CBC:1;
|
||||
uint8_t DRV_OFF:1;
|
||||
};
|
||||
uint8_t reg;
|
||||
} Control__4;
|
||||
|
||||
|
||||
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t CSA_GAIN:2;
|
||||
uint8_t EN_ASR:1;
|
||||
uint8_t EN_AAR:1;
|
||||
uint8_t :2;
|
||||
uint8_t ILIM_RECIR:1;
|
||||
uint8_t :1;
|
||||
};
|
||||
uint8_t reg;
|
||||
} Control__5;
|
||||
|
||||
|
||||
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t BUCK_DIS:1;
|
||||
uint8_t BUCK_SEL:2;
|
||||
uint8_t BUCK_CL:1;
|
||||
uint8_t BUCK_PS_DIS:1;
|
||||
uint8_t :2;
|
||||
};
|
||||
uint8_t reg;
|
||||
} Control__6;
|
||||
|
||||
|
||||
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t DLY_TARGET:4;
|
||||
uint8_t DLYCMP_EN:1;
|
||||
uint8_t :3;
|
||||
};
|
||||
uint8_t reg;
|
||||
} Control__10;
|
||||
|
||||
|
||||
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t FAULT:1;
|
||||
uint8_t OT:1;
|
||||
uint8_t OVP:1;
|
||||
uint8_t NPOR:1;
|
||||
uint8_t OCP:1;
|
||||
uint8_t SPI_FLT:1;
|
||||
uint8_t BK_FLT:1;
|
||||
uint8_t :1;
|
||||
};
|
||||
uint8_t reg;
|
||||
} IC_Status;
|
||||
|
||||
|
||||
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t OCP_LA:1;
|
||||
uint8_t OCP_HA:1;
|
||||
uint8_t OCP_LB:1;
|
||||
uint8_t OCP_HB:1;
|
||||
uint8_t OCP_LC:1;
|
||||
uint8_t OCP_HC:1;
|
||||
uint8_t OTS:1;
|
||||
uint8_t OTW:1;
|
||||
};
|
||||
uint8_t reg;
|
||||
} Status__1;
|
||||
|
||||
|
||||
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t SPI_ADDR_FLT:1;
|
||||
uint8_t SPI_SCLK_FLT:1;
|
||||
uint8_t SPI_PARITY:1;
|
||||
uint8_t VCP_UV:1;
|
||||
uint8_t BUCK_UV:1;
|
||||
uint8_t BUCK_OCP:1;
|
||||
uint8_t OTP_ERR:1;
|
||||
uint8_t :1;
|
||||
};
|
||||
uint8_t reg;
|
||||
} Status__2;
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user