Files
lemon-pepper-stepper/firmware/lib/Arduino-FOC-drivers/src/encoders/tle5012b/STM32TLE5012B.cpp
2023-11-09 19:02:15 -05:00

160 lines
4.7 KiB
C++

#include "STM32TLE5012B.h"
#if defined(_STM32_DEF_)
#include "utility/spi_com.h"
extern "C" uint32_t spi_getClkFreqInst(SPI_TypeDef *spi_inst);
TLE5012B::TLE5012B(int data, int sck, int nCS, uint32_t freq) {
_data = data;
_sck = sck;
_nCS = nCS;
_freq = freq;
};
TLE5012B::~TLE5012B() {
};
void TLE5012B::init() {
pinMode(_nCS, OUTPUT);
digitalWrite(_nCS, HIGH);
// initialize pins
GPIO_InitTypeDef gpio;
gpio.Pin = digitalPinToBitMask(_data);
gpio.Mode = GPIO_MODE_AF_PP;
gpio.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(digitalPinToPort(_data), &gpio);
gpio.Pin = digitalPinToBitMask(_sck);
gpio.Mode = GPIO_MODE_AF_PP;
gpio.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(digitalPinToPort(_sck), &gpio);
SPI_TypeDef *spi_data = (SPI_TypeDef*)pinmap_peripheral(digitalPinToPinName(_data), PinMap_SPI_MOSI);
SPI_TypeDef *spi_sclk = (SPI_TypeDef*)pinmap_peripheral(digitalPinToPinName(_sck), PinMap_SPI_SCLK);
SPI_TypeDef *spi_inst = (SPI_TypeDef*)pinmap_merge_peripheral(spi_data, spi_sclk);
pinmap_pinout(digitalPinToPinName(_data), PinMap_SPI_MOSI);
pinmap_pinout(digitalPinToPinName(_sck), PinMap_SPI_SCLK);
#if defined SPI1_BASE
if (spi_inst == SPI1) {
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_SPI1_FORCE_RESET();
__HAL_RCC_SPI1_RELEASE_RESET();
}
#endif
#if defined SPI2_BASE
if (spi_inst == SPI2) {
__HAL_RCC_SPI2_CLK_ENABLE();
__HAL_RCC_SPI2_FORCE_RESET();
__HAL_RCC_SPI2_RELEASE_RESET();
}
#endif
#if defined SPI3_BASE
if (spi_inst == SPI3) {
__HAL_RCC_SPI3_CLK_ENABLE();
__HAL_RCC_SPI3_FORCE_RESET();
__HAL_RCC_SPI3_RELEASE_RESET();
}
#endif
#if defined SPI4_BASE
if (spi_inst == SPI4) {
__HAL_RCC_SPI4_CLK_ENABLE();
__HAL_RCC_SPI4_FORCE_RESET();
__HAL_RCC_SPI4_RELEASE_RESET();
}
#endif
#if defined SPI5_BASE
if (spi_inst == SPI5) {
__HAL_RCC_SPI5_CLK_ENABLE();
__HAL_RCC_SPI5_FORCE_RESET();
__HAL_RCC_SPI5_RELEASE_RESET();
}
#endif
#if defined SPI6_BASE
if (spi_inst == SPI6) {
__HAL_RCC_SPI6_CLK_ENABLE();
__HAL_RCC_SPI6_FORCE_RESET();
__HAL_RCC_SPI6_RELEASE_RESET();
}
#endif
_spi.Instance = spi_inst;
_spi.Init.Direction = SPI_DIRECTION_1LINE;
_spi.Init.Mode = SPI_MODE_MASTER;
_spi.Init.DataSize = SPI_DATASIZE_8BIT;
_spi.Init.CLKPolarity = SPI_POLARITY_LOW;
_spi.Init.CLKPhase = SPI_PHASE_2EDGE;
_spi.Init.NSS = SPI_NSS_SOFT;
_spi.Init.FirstBit = SPI_FIRSTBIT_MSB;
_spi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
_spi.Init.CRCPolynomial = 7;
_spi.Init.TIMode = SPI_TIMODE_DISABLE;
#if defined(SPI_NSS_PULSE_DISABLE)
_spi.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
#endif
uint32_t spi_freq = spi_getClkFreqInst(spi_inst);
if (_freq >= (spi_freq / SPI_SPEED_CLOCK_DIV2_MHZ)) {
_spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
} else if (_freq >= (spi_freq / SPI_SPEED_CLOCK_DIV4_MHZ)) {
_spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
} else if (_freq >= (spi_freq / SPI_SPEED_CLOCK_DIV8_MHZ)) {
_spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
} else if (_freq >= (spi_freq / SPI_SPEED_CLOCK_DIV16_MHZ)) {
_spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
} else if (_freq >= (spi_freq / SPI_SPEED_CLOCK_DIV32_MHZ)) {
_spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
} else if (_freq >= (spi_freq / SPI_SPEED_CLOCK_DIV64_MHZ)) {
_spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
} else if (_freq >= (spi_freq / SPI_SPEED_CLOCK_DIV128_MHZ)) {
_spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;
} else {
_spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
}
if (HAL_SPI_Init(&_spi) != HAL_OK) {
// setup error
Serial.println("TLE5012B setup error");
}
};
uint16_t TLE5012B::readRawAngle() {
uint8_t data[4];
readBytes(TLE5012B_ANGLE_REG, data, 2);
return (((uint16_t)data[0] << 8) | data[1]) & 0x7FFF;
};
float TLE5012B::getCurrentAngle() {
return ((float)readRawAngle())/TLE5012B_CPR * _2PI;
}; // angle in radians, return current value
void TLE5012B::readBytes(uint16_t reg, uint8_t *data, uint8_t len) {
digitalWrite(_nCS, LOW);
reg |= TLE5012B_READ_REGISTER + (len>>1);
uint8_t txbuffer[2] = { (uint8_t)(reg >> 8), (uint8_t)(reg & 0x00FF) };
HAL_SPI_Transmit(&_spi, txbuffer, 2, 100); // TODO check return value for error, timeout
//delayMicroseconds(1);
HAL_SPI_Receive(&_spi, data, len + 2, 100);
digitalWrite(_nCS, HIGH);
};
#endif