try to fix submodule
This commit is contained in:
146
firmware/lib/Arduino-FOC-drivers/src/encoders/ma330/MA330.cpp
Normal file
146
firmware/lib/Arduino-FOC-drivers/src/encoders/ma330/MA330.cpp
Normal file
@@ -0,0 +1,146 @@
|
||||
#include "MA330.h"
|
||||
|
||||
MA330::MA330(SPISettings settings, int nCS) : settings(settings), nCS(nCS) {
|
||||
|
||||
};
|
||||
MA330::~MA330() {
|
||||
|
||||
};
|
||||
|
||||
void MA330::init(SPIClass* _spi) {
|
||||
spi = _spi;
|
||||
if (nCS >= 0) {
|
||||
pinMode(nCS, OUTPUT);
|
||||
digitalWrite(nCS, HIGH);
|
||||
}
|
||||
};
|
||||
|
||||
float MA330::getCurrentAngle() {
|
||||
return (readRawAngle() * _2PI)/MA330_CPR;
|
||||
}; // angle in radians, return current value
|
||||
|
||||
uint16_t MA330::readRawAngle() {
|
||||
uint16_t angle = transfer16(0x0000);
|
||||
return angle;
|
||||
}; // 9-14bit angle value
|
||||
|
||||
uint16_t MA330::getZero() {
|
||||
uint16_t result = readRegister(MA330_REG_ZERO_POSITION_MSB)<<8;
|
||||
result |= readRegister(MA330_REG_ZERO_POSITION_LSB);
|
||||
return result;
|
||||
};
|
||||
uint8_t MA330::getBiasCurrentTrimming() {
|
||||
return readRegister(MA330_REG_BCT);
|
||||
};
|
||||
bool MA330::isBiasCurrrentTrimmingX() {
|
||||
return (readRegister(MA330_REG_ET) & 0x01)==0x01;
|
||||
};
|
||||
bool MA330::isBiasCurrrentTrimmingY() {
|
||||
return (readRegister(MA330_REG_ET) & 0x02)==0x02;
|
||||
};
|
||||
uint16_t MA330::getPulsesPerTurn() {
|
||||
uint16_t result = readRegister(MA330_REG_ILIP_PPT_LSB)>>6;
|
||||
result |= ((uint16_t)readRegister(MA330_REG_PPT_MSB))<<2;
|
||||
return result+1;
|
||||
};
|
||||
uint8_t MA330::getIndexLength() {
|
||||
return (readRegister(MA330_REG_ILIP_PPT_LSB)>>2)&0x0F;
|
||||
};
|
||||
uint8_t MA330::getNumberPolePairs() {
|
||||
return (readRegister(MA330_REG_NPP)>>5)&0x07;;
|
||||
};
|
||||
uint8_t MA330::getRotationDirection() {
|
||||
return (readRegister(MA330_REG_RD)>>7);
|
||||
};
|
||||
uint8_t MA330::getFieldStrengthHighThreshold() {
|
||||
return (readRegister(MA330_REG_MGLT_MGHT)>>2)&0x07;
|
||||
};
|
||||
uint8_t MA330::getFieldStrengthLowThreshold() {
|
||||
return (readRegister(MA330_REG_MGLT_MGHT)>>5)&0x07;
|
||||
};
|
||||
uint8_t MA330::getFilterWidth() {
|
||||
return readRegister(MA330_REG_FW);
|
||||
};
|
||||
uint8_t MA330::getHysteresis() {
|
||||
return readRegister(MA330_REG_HYS);
|
||||
};
|
||||
FieldStrength MA330::getFieldStrength() {
|
||||
return (FieldStrength)(readRegister(MA330_REG_MGH_MGL)>>6);
|
||||
};
|
||||
|
||||
|
||||
|
||||
void MA330::setZero(uint16_t value) {
|
||||
writeRegister(MA330_REG_ZERO_POSITION_MSB, value>>8);
|
||||
writeRegister(MA330_REG_ZERO_POSITION_LSB, value&0x00FF);
|
||||
};
|
||||
void MA330::setBiasCurrentTrimming(uint8_t value) {
|
||||
writeRegister(MA330_REG_BCT, value);
|
||||
};
|
||||
void MA330::setBiasCurrrentTrimmingEnabled(bool Xenabled, bool Yenabled) {
|
||||
uint8_t val = Xenabled ? 0x01 : 0x00;
|
||||
val |= (Yenabled ? 0x02 : 0x00);
|
||||
writeRegister(MA330_REG_ET, val);
|
||||
};
|
||||
void MA330::setPulsesPerTurn(uint16_t value) {
|
||||
uint16_t pptVal = value - 1;
|
||||
writeRegister(MA330_REG_PPT_MSB, pptVal>>2);
|
||||
uint8_t val = readRegister(MA330_REG_ILIP_PPT_LSB);
|
||||
val &= 0x3F;
|
||||
val |= (pptVal&0x03)<<6;
|
||||
writeRegister(MA330_REG_ILIP_PPT_LSB, val);
|
||||
};
|
||||
void MA330::setIndexLength(uint8_t value) {
|
||||
uint8_t val = readRegister(MA330_REG_ILIP_PPT_LSB);
|
||||
val &= 0xC0;
|
||||
val |= ((value<<2)&0x3F);
|
||||
writeRegister(MA330_REG_ILIP_PPT_LSB, val);
|
||||
};
|
||||
void MA330::setNumberPolePairs(uint8_t value) {
|
||||
uint8_t val = readRegister(MA330_REG_NPP);
|
||||
val &= 0x1F;
|
||||
val |= (value<<5);
|
||||
writeRegister(MA330_REG_NPP, val);
|
||||
};
|
||||
void MA330::setRotationDirection(uint8_t value) {
|
||||
if (value==0)
|
||||
writeRegister(MA330_REG_RD, 0x00);
|
||||
else
|
||||
writeRegister(MA330_REG_RD, 0x80);
|
||||
};
|
||||
void MA330::setFilterWidth(uint8_t value) {
|
||||
writeRegister(MA330_REG_FW, value);
|
||||
};
|
||||
void MA330::setHysteresis(uint8_t value) {
|
||||
writeRegister(MA330_REG_HYS, value);
|
||||
};
|
||||
void MA330::setFieldStrengthThresholds(uint8_t high, uint8_t low) {
|
||||
uint8_t val = (low<<5) | (high<<2);
|
||||
writeRegister(MA330_REG_MGLT_MGHT, val);
|
||||
};
|
||||
|
||||
|
||||
uint16_t MA330::transfer16(uint16_t outValue) {
|
||||
if (nCS >= 0)
|
||||
digitalWrite(nCS, LOW);
|
||||
spi->beginTransaction(settings);
|
||||
uint16_t value = spi->transfer16(outValue);
|
||||
spi->endTransaction();
|
||||
if (nCS >= 0)
|
||||
digitalWrite(nCS, HIGH);
|
||||
return value;
|
||||
};
|
||||
uint8_t MA330::readRegister(uint8_t reg) {
|
||||
uint16_t cmd = 0x4000 | ((reg&0x001F)<<8);
|
||||
uint16_t value = transfer16(cmd);
|
||||
delayMicroseconds(1);
|
||||
value = transfer16(0x0000);
|
||||
return value>>8;
|
||||
};
|
||||
uint8_t MA330::writeRegister(uint8_t reg, uint8_t value) {
|
||||
uint16_t cmd = 0x8000 | ((reg&0x1F)<<8) | value;
|
||||
uint16_t result = transfer16(cmd);
|
||||
delay(20); // 20ms delay required
|
||||
result = transfer16(0x0000);
|
||||
return result>>8;
|
||||
};
|
||||
82
firmware/lib/Arduino-FOC-drivers/src/encoders/ma330/MA330.h
Normal file
82
firmware/lib/Arduino-FOC-drivers/src/encoders/ma330/MA330.h
Normal file
@@ -0,0 +1,82 @@
|
||||
#ifndef __MA330_H__
|
||||
#define __MA330_H__
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "SPI.h"
|
||||
|
||||
enum FieldStrength : uint8_t {
|
||||
FS_NORMAL = 0x00,
|
||||
FS_LOW = 0x01,
|
||||
FS_HIGH = 0x02,
|
||||
FS_ERR = 0x03 // impossible state
|
||||
};
|
||||
|
||||
|
||||
#define _2PI 6.28318530718f
|
||||
#define MA330_CPR 65536.0f
|
||||
|
||||
#define MA330_REG_ZERO_POSITION_LSB 0x00
|
||||
#define MA330_REG_ZERO_POSITION_MSB 0x01
|
||||
#define MA330_REG_BCT 0x02
|
||||
#define MA330_REG_ET 0x03
|
||||
#define MA330_REG_ILIP_PPT_LSB 0x04
|
||||
#define MA330_REG_PPT_MSB 0x05
|
||||
#define MA330_REG_MGLT_MGHT 0x06
|
||||
#define MA330_REG_NPP 0x07
|
||||
#define MA330_REG_RD 0x09
|
||||
#define MA330_REG_FW 0x0E
|
||||
#define MA330_REG_HYS 0x10
|
||||
#define MA330_REG_MGH_MGL 0x1B
|
||||
|
||||
#define MA330_BITORDER MSBFIRST
|
||||
|
||||
static SPISettings MA330SPISettings(1000000, MA330_BITORDER, SPI_MODE3); // @suppress("Invalid arguments")
|
||||
|
||||
class MA330 {
|
||||
public:
|
||||
MA330(SPISettings settings = MA330SPISettings, int nCS = -1);
|
||||
virtual ~MA330();
|
||||
|
||||
virtual void init(SPIClass* _spi = &SPI);
|
||||
|
||||
float getCurrentAngle(); // angle in radians, return current value
|
||||
|
||||
uint16_t readRawAngle(); // 9-14bit angle value
|
||||
|
||||
uint16_t getZero();
|
||||
uint8_t getBiasCurrentTrimming();
|
||||
bool isBiasCurrrentTrimmingX();
|
||||
bool isBiasCurrrentTrimmingY();
|
||||
uint16_t getPulsesPerTurn();
|
||||
uint8_t getIndexLength();
|
||||
uint8_t getNumberPolePairs();
|
||||
uint8_t getRotationDirection();
|
||||
uint8_t getFilterWidth();
|
||||
uint8_t getHysteresis();
|
||||
uint8_t getFieldStrengthHighThreshold();
|
||||
uint8_t getFieldStrengthLowThreshold();
|
||||
FieldStrength getFieldStrength();
|
||||
|
||||
void setZero(uint16_t);
|
||||
void setBiasCurrentTrimming(uint8_t);
|
||||
void setBiasCurrrentTrimmingEnabled(bool Xenabled, bool Yenabled);
|
||||
void setPulsesPerTurn(uint16_t);
|
||||
void setIndexLength(uint8_t);
|
||||
void setNumberPolePairs(uint8_t);
|
||||
void setRotationDirection(uint8_t);
|
||||
void setFilterWidth(uint8_t);
|
||||
void setHysteresis(uint8_t);
|
||||
void setFieldStrengthThresholds(uint8_t high, uint8_t low);
|
||||
|
||||
private:
|
||||
SPIClass* spi;
|
||||
SPISettings settings;
|
||||
int nCS = -1;
|
||||
|
||||
uint16_t transfer16(uint16_t outValue);
|
||||
uint8_t readRegister(uint8_t reg);
|
||||
uint8_t writeRegister(uint8_t reg, uint8_t value);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "./MagneticSensorMA330.h"
|
||||
#include "common/foc_utils.h"
|
||||
#include "common/time_utils.h"
|
||||
|
||||
MagneticSensorMA330::MagneticSensorMA330(int nCS, SPISettings settings) : MA330(settings, nCS) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
MagneticSensorMA330::~MagneticSensorMA330(){
|
||||
|
||||
}
|
||||
|
||||
|
||||
void MagneticSensorMA330::init(SPIClass* _spi) {
|
||||
this->MA330::init(_spi);
|
||||
this->Sensor::init();
|
||||
}
|
||||
|
||||
|
||||
float MagneticSensorMA330::getSensorAngle() {
|
||||
float angle_data = readRawAngle();
|
||||
angle_data = ( angle_data / (float)MA330_CPR) * _2PI;
|
||||
// return the shaft angle
|
||||
return angle_data;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef __MAGNETIC_SENSOR_MA330_H__
|
||||
#define __MAGNETIC_SENSOR_MA330_H__
|
||||
|
||||
|
||||
#include "common/base_classes/Sensor.h"
|
||||
#include "./MA330.h"
|
||||
|
||||
class MagneticSensorMA330 : public Sensor, public MA330 {
|
||||
public:
|
||||
MagneticSensorMA330(int nCS = -1, SPISettings settings = MA330SPISettings);
|
||||
virtual ~MagneticSensorMA330();
|
||||
|
||||
virtual float getSensorAngle() override;
|
||||
|
||||
virtual void init(SPIClass* _spi = &SPI);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,66 @@
|
||||
# MA330 SimpleFOC driver
|
||||
|
||||
While MA330 absolute position magnetic rotary encoder is supported by the standard MagneticSensorSPI driver included in the base distribution, this MA330-specific driver includes some optimisations:
|
||||
|
||||
- access to the other registers of the MA330
|
||||
- this driver directly reads the angle with one call to SPI
|
||||
- this will halve the number of 16-bit SPI transfers per simpleFOC loop iteration
|
||||
|
||||
|
||||
## Hardware setup
|
||||
|
||||
Connect as per normal for your SPI bus. No special hardware setup is needed to use this driver.
|
||||
|
||||
## Software setup
|
||||
|
||||
Its actually easier to use than the standard SPI sensor class, because it is less generic:
|
||||
|
||||
```c++
|
||||
#include "Arduino.h"
|
||||
#include "Wire.h"
|
||||
#include "SPI.h"
|
||||
#include "SimpleFOC.h"
|
||||
#include "SimpleFOCDrivers.h"
|
||||
#include "encoders/MA330/MagneticSensorMA330.h"
|
||||
|
||||
#define SENSOR1_CS 5 // some digital pin that you're using as the nCS pin
|
||||
MagneticSensorMA330 sensor1(SENSOR1_CS);
|
||||
|
||||
|
||||
void setup() {
|
||||
sensor1.init();
|
||||
}
|
||||
```
|
||||
|
||||
Set some options:
|
||||
|
||||
```c++
|
||||
MagneticSensorMA330 sensor1(SENSOR1_CS, true, mySPISettings);
|
||||
```
|
||||
|
||||
Use another SPI bus:
|
||||
|
||||
```c++
|
||||
void setup() {
|
||||
sensor1.init(SPI2);
|
||||
}
|
||||
```
|
||||
|
||||
Here's how you can use it:
|
||||
|
||||
```c++
|
||||
// update the sensor (only needed if using the sensor without a motor)
|
||||
sensor1.update();
|
||||
|
||||
// get the angle, in radians, including full rotations
|
||||
float a1 = sensor1.getAngle();
|
||||
|
||||
// get the velocity, in rad/s - note: you have to call getAngle() on a regular basis for it to work
|
||||
float v1 = sensor1.getVelocity();
|
||||
|
||||
// get the angle, in radians, no full rotations
|
||||
float a2 = sensor1.getCurrentAngle();
|
||||
|
||||
// get the raw 14 bit value
|
||||
uint16_t raw = sensor1.readRawAngle();
|
||||
```
|
||||
Reference in New Issue
Block a user