system/lib/driver/tmc2240.c

220 lines
7.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "tmc2240.h"
tmc2240_t _tmc2240[TMC2240_MAX];
static void tmc2240_write(tmc2240_index_e index, uint8_t *data)
{
DBG_ASSERT(index < TMC2240_MAX __DBG_LINE);
tmc2240_t *tmc = &_tmc2240[index];
DBG_ASSERT(tmc != NULL __DBG_LINE);
DBG_ASSERT(tmc->spi != NULL __DBG_LINE);
tmc->spi->gpios.cs->reset(*tmc->spi->gpios.cs);
for (uint16_t i = 0; i < 5; i++)
{
tmc->spi->interface.u.normal.spi_send(tmc->spi, data[i]);
}
tmc->spi->gpios.cs->set(*tmc->spi->gpios.cs);
}
static void tmc2240_read(tmc2240_index_e index, uint8_t *wdata, uint8_t *rdata)
{
DBG_ASSERT(index < TMC2240_MAX __DBG_LINE);
tmc2240_t *tmc = &_tmc2240[index];
DBG_ASSERT(tmc != NULL __DBG_LINE);
DBG_ASSERT(tmc->spi != NULL __DBG_LINE);
tmc->spi->gpios.cs->reset(*tmc->spi->gpios.cs);
for (uint16_t i = 0; i < 5; i++)
{
rdata[i] = tmc->spi->interface.u.normal.spi_send(tmc->spi, wdata[i]);
}
tmc->spi->gpios.cs->set(*tmc->spi->gpios.cs);
__NOP();
__NOP();
__NOP();
tmc->spi->gpios.cs->reset(*tmc->spi->gpios.cs);
for (uint16_t i = 0; i < 5; i++)
{
rdata[i] = tmc->spi->interface.u.normal.spi_send(tmc->spi, wdata[i]);
}
tmc->spi->gpios.cs->set(*tmc->spi->gpios.cs);
}
static void tmc2240_reg_write(tmc2240_index_e index, uint8_t reg, uint32_t data)
{
DBG_ASSERT(index < TMC2240_MAX __DBG_LINE);
tmc2240_t *tmc = &_tmc2240[index];
DBG_ASSERT(tmc != NULL __DBG_LINE);
DBG_ASSERT(tmc->spi != NULL __DBG_LINE);
uint8_t wdata[5] = {0};
wdata[0] = TMC2240_HIGHT_BIT | reg;
wdata[1] = (data >> 24) & 0xFF;
wdata[2] = (data >> 16) & 0xFF;
wdata[3] = (data >> 8) & 0xFF;
wdata[4] = data & 0xFF;
tmc2240_write(index, wdata);
}
static uint32_t tmc2240_reg_read(tmc2240_index_e index, uint8_t reg)
{
DBG_ASSERT(index < TMC2240_MAX __DBG_LINE);
tmc2240_t *tmc = &_tmc2240[index];
DBG_ASSERT(tmc != NULL __DBG_LINE);
DBG_ASSERT(tmc->spi != NULL __DBG_LINE);
uint8_t wdata[5] = {0};
uint8_t rdata[5] = {0};
wdata[0] = reg;
tmc2240_read(index, wdata, rdata);
return (rdata[1] << 24) | (rdata[2] << 16) | (rdata[3] << 8) | rdata[4];
}
/**
* @brief 配置TMC2240步进电机驱动器
*
* 该函数用于配置TMC2240步进电机驱动器的各种参数包括步进电机的工作模式、加减速曲线等。
*
* @param index TMC2240步进电机驱动器的索引用于指定要配置的驱动器。
*/
static void tmc2240_config_write(tmc2240_index_e index)
{
DBG_ASSERT(index < TMC2240_MAX __DBG_LINE);
tmc2240_t *tmc = &_tmc2240[index];
DBG_ASSERT(tmc != NULL __DBG_LINE);
tmc->config.gconf.data = 0x00000000;
tmc->config.chopconf.data = 0x00410153;
tmc->config.chopconf.bits.mres = TMC2240_MRES_8;
tmc->config.drvconf.data = 0x00000021;
tmc->config.global_scaler.data = 0x00000000;
tmc->config.ihold_irun.data = 0x00071f1f;
tmc->config.pwmconf.data = 0xC44C261E;
tmc->config.gstat.data = 0x00000007;
tmc2240_reg_write(index, TMC2240_GCONF, tmc->config.gconf.data);
tmc2240_reg_write(index, TMC2240_CHOPCONF, tmc->config.chopconf.data);
tmc2240_reg_write(index, TMC2240_DRV_CONF, tmc->config.drvconf.data);
tmc2240_reg_write(index, TMC2240_GLOBAL_SCALER, tmc->config.global_scaler.data);
tmc2240_reg_write(index, TMC2240_IHOLD_IRUN, tmc->config.ihold_irun.data);
tmc2240_reg_write(index, TMC2240_PWMCONF, tmc->config.pwmconf.data);
tmc2240_reg_write(index, TMC2240_GSTAT, tmc->config.gstat.data);
}
static void _tmc2240_enable(tmc2240_index_e index, BOOL enable)
{
DBG_ASSERT(index < TMC2240_MAX __DBG_LINE);
tmc2240_t *tmc = &_tmc2240[index];
DBG_ASSERT(tmc != NULL __DBG_LINE);
if (enable == TRUE)
{
tmc->en->reset(*tmc->en);
PWM_START(tmc->timer, tmc->time_ch);
}
else
{
tmc->en->set(*tmc->en);
PWM_STOP(tmc->timer, tmc->time_ch);
}
}
static void _tmc2240_direction(tmc2240_index_e index, tmc2240_direction_e dir)
{
DBG_ASSERT(index < TMC2240_MAX __DBG_LINE);
tmc2240_t *tmc = &_tmc2240[index];
DBG_ASSERT(tmc != NULL __DBG_LINE);
if (dir == TMC2240_FORWARD)
{
tmc->dir->reset(*tmc->dir);
}
else
{
tmc->dir->set(*tmc->dir);
}
}
void tmc2240_init(tmc2240_index_e index, SPI_TypeDef *SPIx, TIM_TypeDef *timer, uint32_t time_ch, spi_gpio_group_t *gpios)
{
DBG_ASSERT(index < TMC2240_MAX __DBG_LINE);
tmc2240_t *tmc = &_tmc2240[index];
tmc->timer = timer;
tmc->time_ch = time_ch;
tmc->spi = spi_create(SPI_TYPE_NORMAL, *gpios, 0);
DBG_ASSERT(tmc->spi != NULL __DBG_LINE);
osel_memset((uint8_t *)&tmc->config, 0, sizeof(tmc2240_config_t));
osel_memset((uint8_t *)&tmc->read_config, 0, sizeof(tmc2240_config_t));
tmc->spi->interface.hardware_enable(tmc->spi, SPIx);
{
tmc->default_tm.sysclk = SystemCoreClock / 1000;
tmc->default_tm.psc = PWM_GET_PSC(tmc->timer);
tmc->default_tm.arr = PWM_GET_ARR(tmc->timer);
tmc->default_tm.freq = PWM_GET_FREQ(tmc->timer);
}
tmc->params.percent = TMC2240_PWM_DUTY_DEFAULT;
tmc->params.arr = 0;
tmc->params.freq = 0;
tmc->params.enable = FALSE;
tmc->params.direction = TMC2240_FORWARD;
tmc2240_config_write(index);
}
tmc2240_t *tmc2240_get(tmc2240_index_e index)
{
DBG_ASSERT(index < TMC2240_MAX __DBG_LINE);
return &_tmc2240[index];
}
void tmc2240_percent(tmc2240_index_e index, float32 percent)
{
DBG_ASSERT(index < TMC2240_MAX __DBG_LINE);
tmc2240_t *tmc = &_tmc2240[index];
DBG_ASSERT(tmc != NULL __DBG_LINE);
PWM_SET_DUTY(tmc->timer, tmc->time_ch, ABS(percent));
}
void tmc2240_config_read(tmc2240_index_e index)
{
DBG_ASSERT(index < TMC2240_MAX __DBG_LINE);
tmc2240_t *tmc = &_tmc2240[index];
DBG_ASSERT(tmc != NULL __DBG_LINE);
tmc->read_config.gconf.data = tmc2240_reg_read(index, TMC2240_GCONF);
tmc->read_config.chopconf.data = tmc2240_reg_read(index, TMC2240_CHOPCONF);
tmc->read_config.drvconf.data = tmc2240_reg_read(index, TMC2240_DRV_CONF);
tmc->read_config.global_scaler.data = tmc2240_reg_read(index, TMC2240_GLOBAL_SCALER);
tmc->read_config.ihold_irun.data = tmc2240_reg_read(index, TMC2240_IHOLD_IRUN);
tmc->read_config.pwmconf.data = tmc2240_reg_read(index, TMC2240_PWMCONF);
tmc->read_config.gstat.data = tmc2240_reg_read(index, TMC2240_GSTAT);
tmc->data.tmc2240_adc_temp = tmc2240_reg_read(index, TMC2240_ADC_TEMP);
tmc->data.tmc2240_temperature = (float32)(tmc->data.tmc2240_adc_temp - 2038) / 7.7;
}
void tmc2240_process(tmc2240_index_e index)
{
DBG_ASSERT(index < TMC2240_MAX __DBG_LINE);
tmc2240_t *tmc = &_tmc2240[index];
DBG_ASSERT(tmc != NULL __DBG_LINE);
_tmc2240_enable(index, tmc->params.enable);
_tmc2240_direction(index, tmc->params.direction);
if (PWM_GET_ARR(tmc->timer) != tmc->params.arr)
{
if (tmc->params.arr == 0)
{
tmc->params.arr = tmc->default_tm.arr;
}
PWM_SET_ARR(tmc->timer, tmc->params.arr);
tmc->params.freq = PWM_GET_FREQ(tmc->timer);
}
tmc2240_percent(index, tmc->params.percent);
}