Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions src/Hardware.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#ifndef HARDWARE_H
#define HARDWARE_H


#include "MagneticSensorSPI.h"

/** Typical configuration for the 14bit AMS AS5147 magnetic sensor over SPI interface */
MagneticSensorSPIConfig_s AS5147_SPI = {
.spi_mode = SPI_MODE1,
.clock_speed = 1000000,
.bit_resolution = 14,
.angle_register = 0xCFFF,
.data_start_bit = 13,
.command_rw_bit = 14,
.command_parity_bit = 15
};

/** Typical configuration for the 14bit MonolithicPower MA730 magnetic sensor over SPI interface */
MagneticSensorSPIConfig_s MA730_SPI = {
.spi_mode = SPI_MODE0,
.clock_speed = 1000000,
.bit_resolution = 14,
.angle_register = 0x0000,
.data_start_bit = 15,
.command_rw_bit = 0, // not required
.command_parity_bit = 0 // parity not implemented
};

/** Typical configuration for the 12bit AMS AS5600 magnetic sensor over I2C interface */
MagneticSensorI2CConfig_s AS5600_I2C = {
.chip_address = 0x36,
.clock_speed = 1000000,
.bit_resolution = 12,
.angle_register = 0x0E,
.data_start_bit = 11
};

/** Typical configuration for the 12bit AMS AS5048 magnetic sensor over I2C interface */
MagneticSensorI2CConfig_s AS5048_I2C = {
.chip_address = 0x40, // highly configurable. if A1 and A2 are held low, this is probable value
.clock_speed = 1000000,
.bit_resolution = 14,
.angle_register = 0xFE,
.data_start_bit = 15
};

#endif
24 changes: 23 additions & 1 deletion src/MagneticSensorI2C.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,35 @@ MagneticSensorI2C::MagneticSensorI2C(uint8_t _chip_address, int _bit_resolution,
// extraction masks
lsb_mask = (uint8_t)( (2 << lsb_used) - 1 );
msb_mask = (uint8_t)( (2 << _bits_used_msb) - 1 );
clock_speed = 400000;
sda_pin = SDA;
scl_pin = SCL;

}

MagneticSensorI2C::MagneticSensorI2C(MagneticSensorI2CConfig_s config){
chip_address = config.chip_address;

// angle read register of the magnetic sensor
angle_register_msb = config.angle_register;
// register maximum value (counts per revolution)
cpr = pow(2, config.bit_resolution);

int bits_used_msb = config.data_start_bit - 7;
lsb_used = config.bit_resolution - bits_used_msb;
// extraction masks
lsb_mask = (uint8_t)( (2 << lsb_used) - 1 );
msb_mask = (uint8_t)( (2 << bits_used_msb) - 1 );
clock_speed = 400000;
sda_pin = SDA;
scl_pin = SCL;

}

void MagneticSensorI2C::init(){

//I2C communication begin
Wire.begin();
Wire.begin(sda_pin, scl_pin, clock_speed);

// velocity calculation init
angle_prev = 0;
Expand Down
25 changes: 24 additions & 1 deletion src/MagneticSensorI2C.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@
#include "FOCutils.h"
#include "Sensor.h"

struct MagneticSensorI2CConfig_s {
int chip_address;
long clock_speed;
int bit_resolution;
int angle_register;
int data_start_bit;
};

class MagneticSensorI2C: public Sensor{
public:
Expand All @@ -17,8 +24,15 @@ class MagneticSensorI2C: public Sensor{
* @param _bits_used_msb number of used bits in msb
*/
MagneticSensorI2C(uint8_t _chip_address, int _bit_resolution, uint8_t _angle_register_msb, int _msb_bits_used);


/**
* MagneticSensorI2C class constructor
* @param config I2C config
*/
MagneticSensorI2C(MagneticSensorI2CConfig_s config);

static MagneticSensorI2C AS5600();

/** sensor initialise pins */
void init();

Expand All @@ -40,8 +54,17 @@ class MagneticSensorI2C: public Sensor{
/** returns 1 because it is the absolute sensor */
int hasAbsoluteZero() override;
/** returns 0 maning it doesn't need search for absolute zero */

int needsAbsoluteZeroSearch() override;

/* the speed of the i2c clock signal */
long clock_speed;

/* the pin used for i2c data */
int sda_pin;

/* the pin used for i2c clock */
int scl_pin;

private:
float cpr; //!< Maximum range of the magnetic sensor
Expand Down
67 changes: 41 additions & 26 deletions src/MagneticSensorSPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,49 @@
// _bit_resolution sensor resolution bit number
// _angle_register - (optional) angle read register - default 0x3FFF
MagneticSensorSPI::MagneticSensorSPI(int cs, float _bit_resolution, int _angle_register){
// chip select pin

chip_select_pin = cs;
// angle read register of the magnetic sensor
angle_register = _angle_register ? _angle_register : DEF_ANGLE_REGISTAR;
// register maximum value (counts per revolution)
cpr = pow(2,_bit_resolution);

spi_mode = SPI_MODE1;
clock_speed = 1000000;
bit_resolution = _bit_resolution;

command_parity_bit = 15; // for backwards compatibilty
command_rw_bit = 14; // for backwards compatibilty
data_start_bit = 13; // for backwards compatibilty

}

MagneticSensorSPI::MagneticSensorSPI(MagneticSensorSPIConfig_s config, int cs){
chip_select_pin = cs;
// angle read register of the magnetic sensor
angle_register = config.angle_register ? config.angle_register : DEF_ANGLE_REGISTAR;
// register maximum value (counts per revolution)
cpr = pow(2, config.bit_resolution);
spi_mode = config.spi_mode;
clock_speed = config.clock_speed;
bit_resolution = config.bit_resolution;

command_parity_bit = config.command_parity_bit; // for backwards compatibilty
command_rw_bit = config.command_rw_bit; // for backwards compatibilty
data_start_bit = config.data_start_bit; // for backwards compatibilty
}

void MagneticSensorSPI::init(){
// 1MHz clock (AMS should be able to accept up to 10MHz)
settings = SPISettings(1000000, MSBFIRST, SPI_MODE1);
settings = SPISettings(clock_speed, MSBFIRST, spi_mode);

//setup pins
pinMode(chip_select_pin, OUTPUT);


//SPI has an internal SPI-device counter, it is possible to call "begin()" from different devices
SPI.begin();
#ifndef ESP_H // if not ESP32 board
SPI.setBitOrder(MSBFIRST); // Set the SPI_1 bit order
SPI.setDataMode(SPI_MODE1) ;
SPI.setDataMode(spi_mode) ;
SPI.setClockDivider(SPI_CLOCK_DIV8);
#endif

Expand Down Expand Up @@ -77,7 +97,7 @@ float MagneticSensorSPI::getVelocity(){
float angle_c = getAngle();
// velocity calculation
float vel = (angle_c - angle_prev)/Ts;

// save variables for future pass
angle_prev = angle_c;
velocity_calc_timestamp = now_us;
Expand Down Expand Up @@ -147,35 +167,28 @@ byte MagneticSensorSPI::spiCalcEvenParity(word value){
* Returns the value of the register
*/
word MagneticSensorSPI::read(word angle_register){
word command = 0b0100000000000000; // PAR=0 R/W=R
command = command | angle_register;

//Add a parity bit on the the MSB
command |= ((word)spiCalcEvenParity(command)<<15);

//Split the command into two bytes
byte right_byte = command & 0xFF;
byte left_byte = ( command >> 8 ) & 0xFF;
word command = angle_register;

if (command_rw_bit > 0) {
command = angle_register | (1 << command_rw_bit);
}
if (command_parity_bit > 0) {
//Add a parity bit on the the MSB
command |= ((word)spiCalcEvenParity(command) << command_parity_bit);
}

#if !defined(_STM32_DEF_) // if not stm chips
//SPI - begin transaction
SPI.beginTransaction(settings);
#endif
//SPI - begin transaction
//SPI.beginTransaction(settings);

//Send the command
digitalWrite(chip_select_pin, LOW);
#ifndef ESP_H // if not ESP32 board
digitalWrite(chip_select_pin, LOW);
#endif
SPI.transfer(left_byte);
SPI.transfer(right_byte);
SPI.transfer16(command);
digitalWrite(chip_select_pin,HIGH);
#ifndef ESP_H // if not ESP32 board
digitalWrite(chip_select_pin,HIGH);
#endif

#if defined( ESP_H ) // if ESP32 board
delayMicroseconds(50);
Expand All @@ -186,18 +199,20 @@ word MagneticSensorSPI::read(word angle_register){
//Now read the response
digitalWrite(chip_select_pin, LOW);
digitalWrite(chip_select_pin, LOW);
left_byte = SPI.transfer(0x00);
right_byte = SPI.transfer(0x00);
word register_value = SPI.transfer16(0x00);
digitalWrite(chip_select_pin, HIGH);
digitalWrite(chip_select_pin,HIGH);

#if !defined(_STM32_DEF_) // if not stm chips
//SPI - end transaction
SPI.endTransaction();
#endif

register_value = register_value >> (1 + data_start_bit - bit_resolution); //this should shift data to the rightmost bits of the word

const static word data_mask = ~(0 >> (16 - bit_resolution));

// Return the data, stripping the parity and error bits
return (( ( left_byte & 0xFF ) << 8 ) | ( right_byte & 0xFF )) & ~0xC000;
return register_value & data_mask; // Return the data, stripping the non data (e.g parity) bits
}

/**
Expand Down
29 changes: 28 additions & 1 deletion src/MagneticSensorSPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@

#define DEF_ANGLE_REGISTAR 0x3FFF

struct MagneticSensorSPIConfig_s {
int spi_mode;
long clock_speed;
int bit_resolution;
int angle_register;
int data_start_bit;
int command_rw_bit;
int command_parity_bit;
};

class MagneticSensorSPI: public Sensor{
public:
/**
Expand All @@ -17,7 +27,12 @@ class MagneticSensorSPI: public Sensor{
* @param angle_register (optional) angle read register - default 0x3FFF
*/
MagneticSensorSPI(int cs, float bit_resolution, int angle_register = 0);

/**
* MagneticSensorSPI class constructor
* @param config SPI config
* @param cs SPI chip select pin
*/
MagneticSensorSPI(MagneticSensorSPIConfig_s config, int cs);

/** sensor initialise pins */
void init();
Expand All @@ -40,7 +55,14 @@ class MagneticSensorSPI: public Sensor{
/** returns 1 because it is the absolute sensor */
int hasAbsoluteZero() override;
/** returns 0 maning it doesn't need search for absolute zero */

int needsAbsoluteZeroSearch() override;

// returns the spi mode (phase/polarity of read/writes) i.e one of SPI_MODE0 | SPI_MODE1 | SPI_MODE2 | SPI_MODE3
int spi_mode;

/* returns the speed of the SPI clock signal */
long clock_speed;


private:
Expand Down Expand Up @@ -72,6 +94,11 @@ class MagneticSensorSPI: public Sensor{
// velocity calculation variables
float angle_prev; //!< angle in previous velocity calculation step
long velocity_calc_timestamp; //!< last velocity calculation timestamp

int bit_resolution; //!< the number of bites of angle data
int command_parity_bit; //!< the bit where parity flag is stored in command
int command_rw_bit; //!< the bit where read/write flag is stored in command
int data_start_bit; //!< the the position of first bit

};

Expand Down
1 change: 1 addition & 0 deletions src/SimpleFOC.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,5 +94,6 @@ void loop() {
#include "MagneticSensorAnalog.h"
#include "HallSensor.h"
#include "BLDCMotor.h"
#include "Hardware.h"

#endif