diff --git a/.gitignore b/.gitignore index 0314127b0..22f4f8064 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,7 @@ workspace.code-workspace *.pro.user *.pro.shared +# CLion +.idea/ .vscode + diff --git a/hwconf/hw_xesc2.c b/hwconf/hw_xesc2.c new file mode 100644 index 000000000..de76b3132 --- /dev/null +++ b/hwconf/hw_xesc2.c @@ -0,0 +1,240 @@ +/* + Copyright 2012-2020 Benjamin Vedder benjamin@vedder.se + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#include "hw.h" + +#include "ch.h" +#include "hal.h" +#include "stm32f4xx_conf.h" +#include "utils.h" +#include "tmc6200.h" +#include "terminal.h" +#include "commands.h" +#include "mc_interface.h" + +// Variables +static volatile bool i2c_running = false; + + +// I2C configuration +static const I2CConfig i2cfg = { + OPMODE_I2C, + 100000, + STD_DUTY_CYCLE +}; + +bool tmc_error() { + return !tmc6200_ok() || palReadPad(GPIOB, 7); +} + +void hw_init_gpio(void) { + // GPIO clock enable + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); + + // LEDs + palSetPadMode(GPIOB, 0, + PAL_MODE_OUTPUT_PUSHPULL | + PAL_STM32_OSPEED_HIGHEST); + palSetPadMode(GPIOB, 1, + PAL_MODE_OUTPUT_PUSHPULL | + PAL_STM32_OSPEED_HIGHEST); + + // ENABLE_GATE + palSetPadMode(GPIOB, 5, + PAL_MODE_OUTPUT_PUSHPULL | + PAL_STM32_OSPEED_HIGHEST); + + ENABLE_GATE(); + + + // GPIOA Configuration: Channel 1 to 3 as alternate function push-pull + palSetPadMode(GPIOA, 8, PAL_MODE_ALTERNATE(GPIO_AF_TIM1) | + PAL_STM32_OSPEED_HIGHEST | + PAL_STM32_PUDR_FLOATING); + palSetPadMode(GPIOA, 9, PAL_MODE_ALTERNATE(GPIO_AF_TIM1) | + PAL_STM32_OSPEED_HIGHEST | + PAL_STM32_PUDR_FLOATING); + palSetPadMode(GPIOA, 10, PAL_MODE_ALTERNATE(GPIO_AF_TIM1) | + PAL_STM32_OSPEED_HIGHEST | + PAL_STM32_PUDR_FLOATING); + + palSetPadMode(GPIOB, 13, PAL_MODE_ALTERNATE(GPIO_AF_TIM1) | + PAL_STM32_OSPEED_HIGHEST | + PAL_STM32_PUDR_FLOATING); + palSetPadMode(GPIOB, 14, PAL_MODE_ALTERNATE(GPIO_AF_TIM1) | + PAL_STM32_OSPEED_HIGHEST | + PAL_STM32_PUDR_FLOATING); + palSetPadMode(GPIOB, 15, PAL_MODE_ALTERNATE(GPIO_AF_TIM1) | + PAL_STM32_OSPEED_HIGHEST | + PAL_STM32_PUDR_FLOATING); + + // Hall sensors + palSetPadMode(HW_HALL_ENC_GPIO1, HW_HALL_ENC_PIN1, PAL_MODE_INPUT_PULLUP); + palSetPadMode(HW_HALL_ENC_GPIO2, HW_HALL_ENC_PIN2, PAL_MODE_INPUT_PULLUP); + palSetPadMode(HW_HALL_ENC_GPIO3, HW_HALL_ENC_PIN3, PAL_MODE_INPUT_PULLUP); + + + // Fault pin + palSetPadMode(GPIOB, 7, PAL_MODE_INPUT_PULLUP); + + // ADC Pins + palSetPadMode(GPIOA, 0, PAL_MODE_INPUT_ANALOG); + palSetPadMode(GPIOA, 1, PAL_MODE_INPUT_ANALOG); + palSetPadMode(GPIOA, 2, PAL_MODE_INPUT_ANALOG); + palSetPadMode(GPIOA, 3, PAL_MODE_INPUT_ANALOG); + palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); + palSetPadMode(GPIOA, 6, PAL_MODE_INPUT_ANALOG); + + palSetPadMode(GPIOC, 0, PAL_MODE_INPUT_ANALOG); + palSetPadMode(GPIOC, 1, PAL_MODE_INPUT_ANALOG); + palSetPadMode(GPIOC, 2, PAL_MODE_INPUT_ANALOG); + palSetPadMode(GPIOC, 3, PAL_MODE_INPUT_ANALOG); + palSetPadMode(GPIOC, 4, PAL_MODE_INPUT_ANALOG); + + tmc6200_init(); +} + +void hw_setup_adc_channels(void) { + // ADC1 regular channels + ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_15Cycles); + ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 2, ADC_SampleTime_15Cycles); + ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 3, ADC_SampleTime_15Cycles); + ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 4, ADC_SampleTime_15Cycles); + ADC_RegularChannelConfig(ADC1, ADC_Channel_Vrefint, 5, ADC_SampleTime_15Cycles); + + // ADC2 regular channels + ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 1, ADC_SampleTime_15Cycles); + ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 2, ADC_SampleTime_15Cycles); + ADC_RegularChannelConfig(ADC2, ADC_Channel_6, 3, ADC_SampleTime_15Cycles); + ADC_RegularChannelConfig(ADC2, ADC_Channel_15, 4, ADC_SampleTime_15Cycles); + ADC_RegularChannelConfig(ADC2, ADC_Channel_0, 5, ADC_SampleTime_15Cycles); + + // ADC3 regular channels + ADC_RegularChannelConfig(ADC3, ADC_Channel_2, 1, ADC_SampleTime_15Cycles); + ADC_RegularChannelConfig(ADC3, ADC_Channel_12, 2, ADC_SampleTime_15Cycles); + ADC_RegularChannelConfig(ADC3, ADC_Channel_3, 3, ADC_SampleTime_15Cycles); + ADC_RegularChannelConfig(ADC3, ADC_Channel_13, 4, ADC_SampleTime_15Cycles); + ADC_RegularChannelConfig(ADC3, ADC_Channel_1, 5, ADC_SampleTime_15Cycles); + + // Injected channels + ADC_InjectedChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_15Cycles); + ADC_InjectedChannelConfig(ADC2, ADC_Channel_11, 1, ADC_SampleTime_15Cycles); + ADC_InjectedChannelConfig(ADC3, ADC_Channel_12, 1, ADC_SampleTime_15Cycles); + ADC_InjectedChannelConfig(ADC1, ADC_Channel_10, 2, ADC_SampleTime_15Cycles); + ADC_InjectedChannelConfig(ADC2, ADC_Channel_11, 2, ADC_SampleTime_15Cycles); + ADC_InjectedChannelConfig(ADC3, ADC_Channel_12, 2, ADC_SampleTime_15Cycles); + ADC_InjectedChannelConfig(ADC1, ADC_Channel_10, 3, ADC_SampleTime_15Cycles); + ADC_InjectedChannelConfig(ADC2, ADC_Channel_11, 3, ADC_SampleTime_15Cycles); + ADC_InjectedChannelConfig(ADC3, ADC_Channel_12, 3, ADC_SampleTime_15Cycles); +} + +void hw_start_i2c(void) { + i2cAcquireBus(&HW_I2C_DEV); + + if (!i2c_running) { + palSetPadMode(HW_I2C_SCL_PORT, HW_I2C_SCL_PIN, + PAL_MODE_ALTERNATE(HW_I2C_GPIO_AF) | + PAL_STM32_OTYPE_OPENDRAIN | + PAL_STM32_OSPEED_MID1 | + PAL_STM32_PUDR_PULLUP); + palSetPadMode(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN, + PAL_MODE_ALTERNATE(HW_I2C_GPIO_AF) | + PAL_STM32_OTYPE_OPENDRAIN | + PAL_STM32_OSPEED_MID1 | + PAL_STM32_PUDR_PULLUP); + + i2cStart(&HW_I2C_DEV, &i2cfg); + i2c_running = true; + } + + i2cReleaseBus(&HW_I2C_DEV); +} + +void hw_stop_i2c(void) { + i2cAcquireBus(&HW_I2C_DEV); + + if (i2c_running) { + palSetPadMode(HW_I2C_SCL_PORT, HW_I2C_SCL_PIN, PAL_MODE_INPUT); + palSetPadMode(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN, PAL_MODE_INPUT); + + i2cStop(&HW_I2C_DEV); + i2c_running = false; + + } + + i2cReleaseBus(&HW_I2C_DEV); +} + +/** + * Try to restore the i2c bus + */ +void hw_try_restore_i2c(void) { + if (i2c_running) { + i2cAcquireBus(&HW_I2C_DEV); + + palSetPadMode(HW_I2C_SCL_PORT, HW_I2C_SCL_PIN, + PAL_STM32_OTYPE_OPENDRAIN | + PAL_STM32_OSPEED_MID1 | + PAL_STM32_PUDR_PULLUP); + + palSetPadMode(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN, + PAL_STM32_OTYPE_OPENDRAIN | + PAL_STM32_OSPEED_MID1 | + PAL_STM32_PUDR_PULLUP); + + palSetPad(HW_I2C_SCL_PORT, HW_I2C_SCL_PIN); + palSetPad(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN); + + chThdSleep(1); + + for(int i = 0;i < 16;i++) { + palClearPad(HW_I2C_SCL_PORT, HW_I2C_SCL_PIN); + chThdSleep(1); + palSetPad(HW_I2C_SCL_PORT, HW_I2C_SCL_PIN); + chThdSleep(1); + } + + // Generate start then stop condition + palClearPad(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN); + chThdSleep(1); + palClearPad(HW_I2C_SCL_PORT, HW_I2C_SCL_PIN); + chThdSleep(1); + palSetPad(HW_I2C_SCL_PORT, HW_I2C_SCL_PIN); + chThdSleep(1); + palSetPad(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN); + + palSetPadMode(HW_I2C_SCL_PORT, HW_I2C_SCL_PIN, + PAL_MODE_ALTERNATE(HW_I2C_GPIO_AF) | + PAL_STM32_OTYPE_OPENDRAIN | + PAL_STM32_OSPEED_MID1 | + PAL_STM32_PUDR_PULLUP); + + palSetPadMode(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN, + PAL_MODE_ALTERNATE(HW_I2C_GPIO_AF) | + PAL_STM32_OTYPE_OPENDRAIN | + PAL_STM32_OSPEED_MID1 | + PAL_STM32_PUDR_PULLUP); + + HW_I2C_DEV.state = I2C_STOP; + i2cStart(&HW_I2C_DEV, &i2cfg); + + i2cReleaseBus(&HW_I2C_DEV); + } +} diff --git a/hwconf/hw_xesc2.h b/hwconf/hw_xesc2.h new file mode 100644 index 000000000..6577ba866 --- /dev/null +++ b/hwconf/hw_xesc2.h @@ -0,0 +1,266 @@ +/* + Copyright 2016 - 2020 Benjamin Vedder benjamin@vedder.se + + This file is part of the VESC firmware. + + The VESC firmware is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + The VESC firmware is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#ifndef HW_XESC2_H_ +#define HW_XESC2_H_ + +#include "tmc6200.h" + +bool tmc_error(void); + +#define HW_NAME "xESC2" + +#define HW_MAJOR 2 +#define HW_MINOR 0 + +// HW properties +#define HW_HAS_TMC6200 +#define HW_HAS_3_SHUNTS +#define HW_HAS_PHASE_SHUNTS + +// Macros +#define ENABLE_GATE() palSetPad(GPIOB, 5) +#define DISABLE_GATE() palClearPad(GPIOB, 5) + +#define DCCAL_ON() +#define DCCAL_OFF() +#define IS_DRV_FAULT() (tmc_error()) + + +#define LED_GREEN_ON() palSetPad(GPIOB, 0) +#define LED_GREEN_OFF() palClearPad(GPIOB, 0) +#define LED_RED_ON() palSetPad(GPIOB, 1) +#define LED_RED_OFF() palClearPad(GPIOB, 1) + + + + +/* + * ADC Vector + * + * 0: IN0 SENS1 + * 1: IN1 SENS2 + * 2: IN2 SENS3 + * 3: IN10 CURR1 + * 4: IN11 CURR2 + * 5: IN12 CURR3 + * 6: IN5 ADC_EXT1 + * 7: IN6 ADC_EXT2 + * 8: IN3 TEMP_PCB + * 9: IN14 TEMP_MOTOR + * 10: IN15 ADC_EXT3, Shutdown on MK3 + * 11: IN13 AN_IN + * 12: Vrefint + * 13: IN0 SENS1 + * 14: IN1 SENS2 + */ + +#define HW_ADC_CHANNELS 15 +#define HW_ADC_INJ_CHANNELS 3 +#define HW_ADC_NBR_CONV 5 + +// ADC Indexes +#define ADC_IND_SENS1 0 +#define ADC_IND_SENS2 1 +#define ADC_IND_SENS3 2 +#define ADC_IND_CURR1 3 +#define ADC_IND_CURR2 4 +#define ADC_IND_CURR3 5 +#define ADC_IND_VIN_SENS 11 +#define ADC_IND_EXT 6 +#define ADC_IND_EXT2 7 +#define ADC_IND_TEMP_MOS 8 +#define ADC_IND_TEMP_MOTOR 9 +#define ADC_IND_VREFINT 12 + + + +// ---------------------------- + +// ADC macros and settings + +// Component parameters (can be overridden) +#ifndef V_REG +#define V_REG 3.3 +#endif +#ifndef VIN_R1 +#define VIN_R1 22000.0 +#endif +#ifndef VIN_R2 +#define VIN_R2 1500.0 +#endif +#ifndef CURRENT_AMP_GAIN +#define CURRENT_AMP_GAIN (5.0 * 0.595) +#endif +#ifndef CURRENT_SHUNT_RES +#define CURRENT_SHUNT_RES 0.033 +#endif + +// We need to scale the ADC_Value because of the voltage divider between the gate driver and the analog inputs +#define GET_CURRENT1() (int)((4095.0f - ((float)ADC_Value[ADC_IND_CURR1]*1.11f))) +#define GET_CURRENT2() (int)((4095.0f - ((float)ADC_Value[ADC_IND_CURR2]*1.11f))) +#define GET_CURRENT3() (int)((4095.0f - ((float)ADC_Value[ADC_IND_CURR3]*1.11f))) + + +// Input voltage +#define GET_INPUT_VOLTAGE() ((V_REG / 4095.0) * (float)ADC_Value[ADC_IND_VIN_SENS] * ((VIN_R1 + VIN_R2) / VIN_R2)) + +// NTC Termistors +#define NTC_RES(adc_val) ((4095.0 * 10000.0) / adc_val - 10000.0) +#define NTC_TEMP(adc_ind) (1.0 / ((logf(NTC_RES(ADC_Value[adc_ind]) / 10000.0) / 3380.0) + (1.0 / 298.15)) - 273.15) + +#define NTC_RES_MOTOR(adc_val) (10000.0 / ((4095.0 / (float)adc_val) - 1.0)) // Motor temp sensor on low side +#define NTC_TEMP_MOTOR(beta) (1.0 / ((logf(NTC_RES_MOTOR(ADC_Value[ADC_IND_TEMP_MOTOR]) / 10000.0) / beta) + (1.0 / 298.15)) - 273.15) + + +// Voltage on ADC channel +#define ADC_VOLTS(ch) ((float)ADC_Value[ch] / 4096.0 * V_REG) + +// Double samples in beginning and end for positive current measurement. +// Useful when the shunt sense traces have noise that causes offset. +#ifndef CURR1_DOUBLE_SAMPLE +#define CURR1_DOUBLE_SAMPLE 0 +#endif +#ifndef CURR2_DOUBLE_SAMPLE +#define CURR2_DOUBLE_SAMPLE 0 +#endif +#ifndef CURR3_DOUBLE_SAMPLE +#define CURR3_DOUBLE_SAMPLE 0 +#endif + +// COMM-port ADC GPIOs +#define HW_ADC_EXT_GPIO GPIOA +#define HW_ADC_EXT_PIN 5 +#define HW_ADC_EXT2_GPIO GPIOA +#define HW_ADC_EXT2_PIN 6 + +// UART Peripheral +#define HW_UART_DEV SD3 +#define HW_UART_GPIO_AF GPIO_AF_USART3 +#define HW_UART_TX_PORT GPIOB +#define HW_UART_TX_PIN 10 +#define HW_UART_RX_PORT GPIOB +#define HW_UART_RX_PIN 11 + + +// ICU Peripheral for servo decoding +#define HW_USE_SERVO_TIM4 +#define HW_ICU_TIMER TIM4 +#define HW_ICU_TIM_CLK_EN() RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE) +#define HW_ICU_DEV ICUD4 +#define HW_ICU_CHANNEL ICU_CHANNEL_1 +#define HW_ICU_GPIO_AF GPIO_AF_TIM4 +#define HW_ICU_GPIO GPIOB +#define HW_ICU_PIN 6 + +// I2C Peripheral +#define HW_I2C_DEV I2CD2 +#define HW_I2C_GPIO_AF GPIO_AF_I2C2 +#define HW_I2C_SCL_PORT GPIOB +#define HW_I2C_SCL_PIN 10 +#define HW_I2C_SDA_PORT GPIOB +#define HW_I2C_SDA_PIN 11 + +// Hall/encoder pins +#define HW_HALL_ENC_GPIO1 GPIOC +#define HW_HALL_ENC_PIN1 6 +#define HW_HALL_ENC_GPIO2 GPIOC +#define HW_HALL_ENC_PIN2 7 +#define HW_HALL_ENC_GPIO3 GPIOC +#define HW_HALL_ENC_PIN3 8 +#define HW_ENC_TIM TIM3 +#define HW_ENC_TIM_AF GPIO_AF_TIM3 +#define HW_ENC_TIM_CLK_EN() RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE) +#define HW_ENC_EXTI_PORTSRC EXTI_PortSourceGPIOC +#define HW_ENC_EXTI_PINSRC EXTI_PinSource8 +#define HW_ENC_EXTI_CH EXTI9_5_IRQn +#define HW_ENC_EXTI_LINE EXTI_Line8 +#define HW_ENC_EXTI_ISR_VEC EXTI9_5_IRQHandler +#define HW_ENC_TIM_ISR_CH TIM3_IRQn +#define HW_ENC_TIM_ISR_VEC TIM3_IRQHandler + + +// SPI pins +#define HW_SPI_DEV SPID1 +#define HW_SPI_GPIO_AF GPIO_AF_SPI1 +#define HW_SPI_PORT_NSS GPIOA +#define HW_SPI_PIN_NSS 4 +#define HW_SPI_PORT_SCK GPIOA +#define HW_SPI_PIN_SCK 5 +#define HW_SPI_PORT_MOSI GPIOA +#define HW_SPI_PIN_MOSI 7 +#define HW_SPI_PORT_MISO GPIOA +#define HW_SPI_PIN_MISO 6 + + +#define TMC6200_MOSI_GPIO GPIOB +#define TMC6200_MOSI_PIN 4 +#define TMC6200_MISO_GPIO GPIOB +#define TMC6200_MISO_PIN 3 +#define TMC6200_SCK_GPIO GPIOC +#define TMC6200_SCK_PIN 10 +#define TMC6200_CS_GPIO GPIOC +#define TMC6200_CS_PIN 9 + +#define HW_RESET_DRV_FAULTS() tmc6200_reset_faults() + + +// Measurement macros +#define ADC_V_L1 ADC_Value[ADC_IND_SENS1] +#define ADC_V_L2 ADC_Value[ADC_IND_SENS2] +#define ADC_V_L3 ADC_Value[ADC_IND_SENS3] +#define ADC_V_ZERO (ADC_Value[ADC_IND_VIN_SENS] / 2) + +// Macros +#define READ_HALL1() palReadPad(HW_HALL_ENC_GPIO1, HW_HALL_ENC_PIN1) +#define READ_HALL2() palReadPad(HW_HALL_ENC_GPIO2, HW_HALL_ENC_PIN2) +#define READ_HALL3() palReadPad(HW_HALL_ENC_GPIO3, HW_HALL_ENC_PIN3) + +// Default setting overrides +#ifndef MCCONF_DEFAULT_MOTOR_TYPE +#define MCCONF_DEFAULT_MOTOR_TYPE MOTOR_TYPE_FOC +#endif +#ifndef MCCONF_L_MAX_ABS_CURRENT +#define MCCONF_L_MAX_ABS_CURRENT 15.0 // The maximum absolute current above which a fault is generated +#endif +#ifndef MCCONF_FOC_SAMPLE_V0_V7 +#define MCCONF_FOC_SAMPLE_V0_V7 false // Run control loop in both v0 and v7 (requires phase shunts) +#endif + +#define MCCONF_L_CURRENT_MAX 2.0 // Current limit in Amperes (Upper) +#define MCCONF_L_CURRENT_MIN -2.0 // Current limit in Amperes (Lower) +#define MCCONF_L_IN_CURRENT_MAX 5.0 // Input current limit in Amperes (Upper) +#define MCCONF_L_IN_CURRENT_MIN -5.0 // Input current limit in Amperes (Lower) + +#define APPCONF_IMU_TYPE IMU_TYPE_OFF + + +// Setting limits +#define HW_LIM_CURRENT -10.0, 10.0 +#define HW_LIM_CURRENT_IN -15.0, 15.0 +#define HW_LIM_CURRENT_ABS 0.0, 15.0 +#define HW_LIM_VIN 6.0, 40.0 +#define HW_LIM_ERPM -200e3, 200e3 +#define HW_LIM_DUTY_MIN 0.0, 0.1 +#define HW_LIM_DUTY_MAX 0.0, 0.99 +#define HW_LIM_TEMP_FET -40.0, 90.0 +#define HW_MAX_CURRENT_OFFSET 620 + + +#endif /* HW_XESC2_H_ */ diff --git a/hwconf/hwconf.mk b/hwconf/hwconf.mk index f4a827982..af9a9d65a 100644 --- a/hwconf/hwconf.mk +++ b/hwconf/hwconf.mk @@ -6,6 +6,11 @@ HWSRC = \ hwconf/drv8316.c \ hwconf/drv8320s.c \ hwconf/drv8323s.c \ + hwconf/luna/luna_display_serial.c \ + hwconf/si8900.c \ + hwconf/tmc6200.c \ + hwconf/shutdown.c + hwconf/tmc6200.c hwconf/luna/bbshd/luna_display_serial.c \ hwconf/luna/m600/luna_m600_display.c \ hwconf/si8900.c \ diff --git a/hwconf/tmc6200.c b/hwconf/tmc6200.c new file mode 100644 index 000000000..4677d7140 --- /dev/null +++ b/hwconf/tmc6200.c @@ -0,0 +1,283 @@ +/* + Copyright 2016 Benjamin Vedder benjamin@vedder.se + + This file is part of the VESC firmware. + + The VESC firmware is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + The VESC firmware is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#include "conf_general.h" +#ifdef HW_HAS_TMC6200 + +#include "tmc6200.h" +#include "../tmc/ic/TMC6200/TMC6200.h" +#include "ch.h" +#include "hal.h" +#include "stm32f4xx_conf.h" +#include "utils.h" +#include "terminal.h" +#include "commands.h" +#include +#include +#include "mc_interface.h" + +// Private functions +static void spi_transfer(uint8_t *in_buf, const uint8_t *out_buf, int length); +static void spi_begin(void); +static void spi_end(void); +static void spi_delay(void); +static void terminal_read_reg(int argc, const char **argv); +static void terminal_write_reg(int argc, const char **argv); +static void terminal_tmc_6200_found(int argc, const char **argv); +static void terminal_read_currents(int argc, const char **argv); + +// Private variables +static mutex_t m_spi_mutex; +static bool tmc6200_found = false; + +bool tmc6200_ok(void) { + return tmc6200_found; +} + +void tmc6200_init(void) { + chMtxObjectInit(&m_spi_mutex); + + // TMC6200 SPI + palSetPadMode(TMC6200_MISO_GPIO, TMC6200_MISO_PIN, PAL_MODE_INPUT); + palSetPadMode(TMC6200_SCK_GPIO, TMC6200_SCK_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); + palSetPadMode(TMC6200_CS_GPIO, TMC6200_CS_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); + palSetPadMode(TMC6200_MOSI_GPIO, TMC6200_MOSI_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); + palSetPad(TMC6200_MOSI_GPIO, TMC6200_MOSI_PIN); + + chThdSleepMilliseconds(100); + + + + terminal_register_command_callback( + "tmc6200_read_reg", + "Read a register from the TMC6200 and print it.", + "[reg]", + terminal_read_reg); + + terminal_register_command_callback( + "tmc6200_write_reg", + "Write to a TMC6200 register.", + "[reg] [hexvalue]", + terminal_write_reg); + terminal_register_command_callback( + "tmc6200_found", + "Check if TMC was found on startup", + "", + terminal_tmc_6200_found); + + terminal_register_command_callback( + "tmc6200_get_currents", + "Read currents", + "", + terminal_read_currents); + + + + // Disable OC + + //tmc6200_set_current_amp_gain(CURRENT_AMP_GAIN); + + // Get version number and enable driver if it matches + int ic_version = (tmc6200_readInt(0, TMC6200_IOIN_OUTPUT) & TMC6200_VERSION_MASK) >> TMC6200_VERSION_SHIFT; + tmc6200_found = ic_version == 0x10; + + if(tmc6200_found) { + tmc6200_write_conf(); + } +} + + +static void terminal_read_currents(int argc, const char **argv) { + // Avoid unused variable warnings + (void)(argc); + (void)(argv); + + commands_printf("volts: %d, %d, %d", ADC_V_L1, ADC_V_L2, ADC_V_L3); + commands_printf("currents: %d, %d, %d", GET_CURRENT1(), GET_CURRENT2(), GET_CURRENT3()); +} + +static void terminal_tmc_6200_found(int argc, const char **argv) { + // Avoid unused variable warnings + (void)(argc); + (void)(argv); + + if(tmc6200_found) { + commands_printf("TMC6200 found"); + } else { + commands_printf("TMC6200 not found"); + } +} + +static void terminal_read_reg(int argc, const char **argv) { + if (argc == 2) { + int reg = -1; + sscanf(argv[1], "%d", ®); + + if (reg >= 0) { + uint32_t res = tmc6200_readInt(0,reg); + char b1[9]; + char b2[9]; + char b3[9]; + char b4[9]; + + utils_byte_to_binary((res >> 24) & 0xFF, b1); + utils_byte_to_binary((res >> 16) & 0xFF, b2); + utils_byte_to_binary((res >> 8) & 0xFF, b3); + utils_byte_to_binary((res) & 0xFF, b4); + + commands_printf("Reg 0x%02x: %s %s %s %s (0x%04x)\n", reg, b1, b2, b3, b4, res); + } else { + commands_printf("Invalid argument(s).\n"); + } + } else { + commands_printf("This command requires one argument.\n"); + } +} + +static void terminal_write_reg(int argc, const char **argv) { + if (argc == 3) { + int reg = -1; + int val = -1; + sscanf(argv[1], "%d", ®); + sscanf(argv[2], "%x", &val); + + if (reg >= 0 && val >= 0) { + tmc6200_writeInt(0, reg, val); + uint32_t res = tmc6200_readInt(0,reg); + + char b1[9]; + char b2[9]; + char b3[9]; + char b4[9]; + + utils_byte_to_binary((res >> 24) & 0xFF, b1); + utils_byte_to_binary((res >> 16) & 0xFF, b2); + utils_byte_to_binary((res >> 8) & 0xFF, b3); + utils_byte_to_binary((res) & 0xFF, b4); + + commands_printf("Reg 0x%02x: %s %s %s %s (0x%04x)\n", reg, b1, b2, b3, b4, res); + } else { + commands_printf("Invalid argument(s).\n"); + } + } else { + commands_printf("This command requires two arguments.\n"); + } +} + + +uint8_t tmc6200_readwriteByte(uint8_t motor, uint8_t data, uint8_t lastTransfer) +{ + // Avoid unused variable warnings. We only have one gate driver, therefore we don't need to read the motor parameter. + (void)(motor); + + spi_begin(); + uint8_t rx = 0; + spi_transfer(&rx, &data, 1); + if (lastTransfer) + { + spi_end(); + } + return rx; +} + + + +static void spi_transfer(uint8_t *in_buf, const uint8_t *out_buf, int length) { + for (int i = 0;i < length;i++) { + uint8_t send = out_buf ? out_buf[i] : 0xFFFF; + uint8_t recieve = 0; + + for (int bit = 0;bit < 8;bit++) { + palWritePad(TMC6200_MOSI_GPIO, TMC6200_MOSI_PIN, send >> 7); + send <<= 1; + + palClearPad(TMC6200_SCK_GPIO, TMC6200_SCK_PIN); + spi_delay(); + + palSetPad(TMC6200_SCK_GPIO, TMC6200_SCK_PIN); + + int r1, r2, r3; + r1 = palReadPad(TMC6200_MISO_GPIO, TMC6200_MISO_PIN); + __NOP(); + r2 = palReadPad(TMC6200_MISO_GPIO, TMC6200_MISO_PIN); + __NOP(); + r3 = palReadPad(TMC6200_MISO_GPIO, TMC6200_MISO_PIN); + + recieve <<= 1; + if (utils_middle_of_3_int(r1, r2, r3)) { + recieve |= 1; + } + + spi_delay(); + } + + if (in_buf) { + in_buf[i] = recieve; + } + } +} + +static void spi_begin(void) { + palSetPad(TMC6200_SCK_GPIO, TMC6200_SCK_PIN); + palClearPad(TMC6200_CS_GPIO, TMC6200_CS_PIN); + spi_delay(); +} + +static void spi_end(void) { + spi_delay(); + palSetPad(TMC6200_CS_GPIO, TMC6200_CS_PIN); +} + +static void spi_delay(void) { + for (volatile int i = 0;i < 10;i++) { + __NOP(); + } +} + +//int tmc6200_read_faults(void) { +// return 1; +//} + + +void tmc6200_reset_faults(void) { + // stay in error, if SPI comms are dead + int ic_version = (tmc6200_readInt(0, TMC6200_IOIN_OUTPUT) & TMC6200_VERSION_MASK) >> TMC6200_VERSION_SHIFT; + tmc6200_found = ic_version == 0x10; + + if(!tmc6200_found) + return; + DISABLE_GATE(); + chThdSleepMilliseconds(100); + ENABLE_GATE(); + + // we need to set enable for this to work, so do this last + tmc6200_write_conf(); +} + +void tmc6200_write_conf(void) { + // Driver comms OK, configure TMC6200 + tmc6200_writeInt(0, TMC6200_GCONF, + (0UL << TMC6200_DISABLE_SHIFT) | + (0UL << TMC6200_SINGLELINE_SHIFT) | + (1UL << TMC6200_FAULTDIRECT_SHIFT)); + tmc6200_writeInt(0, TMC6200_GSTAT, 0xFFFF); + tmc6200_writeInt(0, TMC6200_SHORT_CONF, (1UL << TMC6200_DISABLE_S2G_SHIFT) | (1UL << TMC6200_DISABLE_S2VS_SHIFT)); +} + +#endif diff --git a/hwconf/tmc6200.h b/hwconf/tmc6200.h new file mode 100644 index 000000000..be85ce771 --- /dev/null +++ b/hwconf/tmc6200.h @@ -0,0 +1,32 @@ +/* + Copyright 2017 Benjamin Vedder benjamin@vedder.se + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#ifndef HWCONF_TMC6200_H_ +#define HWCONF_TMC6200_H_ + +#include "datatypes.h" + +// Functions +bool tmc6200_ok(void); +void tmc6200_init(void); +//int tmc6200_read_faults(void); +void tmc6200_reset_faults(void); +void tmc6200_write_conf(void); + + + +#endif /* HWCONF_TMC6200_H_ */ diff --git a/make/fw.mk b/make/fw.mk index 8f7503a8e..3896add75 100755 --- a/make/fw.mk +++ b/make/fw.mk @@ -110,6 +110,7 @@ include libcanard/canard.mk include imu/imu.mk include blackmagic/blackmagic.mk include encoder/encoder.mk +include tmc/tmc.mk ifeq ($(USE_LISPBM),1) include lispBM/lispbm.mk @@ -145,6 +146,7 @@ CSRC = $(STARTUPSRC) \ $(BLACKMAGICSRC) \ qmlui/qmlui.c \ $(ENCSRC) \ + $(TMCSRC) conf_custom.c ifeq ($(USE_LISPBM),1) @@ -190,7 +192,8 @@ INCDIR = $(STARTUPINC) $(KERNINC) $(PORTINC) $(OSALINC) \ qmlui \ qmlui/hw \ qmlui/app \ - $(ENCINC) + $(ENCINC) \ + $(TMCINC) include comm/comm.mk include motor/motor.mk diff --git a/tmc/ic/TMC6200/TMC6200.c b/tmc/ic/TMC6200/TMC6200.c new file mode 100644 index 000000000..0e49a4b4a --- /dev/null +++ b/tmc/ic/TMC6200/TMC6200.c @@ -0,0 +1,45 @@ +/* + * TMC6200.c + * + * Created on: 14.03.2018 + * Author: ED + */ + +#include "TMC6200.h" + +// => SPI wrapper +extern uint8_t tmc6200_readwriteByte(uint8_t motor, uint8_t data, uint8_t lastTransfer); +// <= SPI wrapper + +// spi access +int32_t tmc6200_readInt(uint8_t motor, uint8_t address) +{ + // clear write bit + address &= 0x7F; + + // write address + tmc6200_readwriteByte(motor, address, 0); + + // read data + int value = tmc6200_readwriteByte(motor, 0, 0); + value <<= 8; + value |= tmc6200_readwriteByte(motor, 0, 0); + value <<= 8; + value |= tmc6200_readwriteByte(motor, 0, 0); + value <<= 8; + value |= tmc6200_readwriteByte(motor, 0, 1); + + return value; +} + +void tmc6200_writeInt(uint8_t motor, uint8_t address, int32_t value) +{ + // write address + tmc6200_readwriteByte(motor, address | TMC6200_WRITE_BIT, 0); + + // write value + tmc6200_readwriteByte(motor, 0xFF & (value>>24), 0); + tmc6200_readwriteByte(motor, 0xFF & (value>>16), 0); + tmc6200_readwriteByte(motor, 0xFF & (value>>8), 0); + tmc6200_readwriteByte(motor, 0xFF & (value>>0), 1); +} diff --git a/tmc/ic/TMC6200/TMC6200.h b/tmc/ic/TMC6200/TMC6200.h new file mode 100644 index 000000000..1be40b7f4 --- /dev/null +++ b/tmc/ic/TMC6200/TMC6200.h @@ -0,0 +1,25 @@ +/* + * TMC6200.h + * + * Created on: 14.03.2018 + * Author: ed + */ + +#ifndef TMC_IC_TMC6200_H_ +#define TMC_IC_TMC6200_H_ + +#include "TMC6200_Register.h" +#include "TMC6200_Constants.h" +#include "TMC6200_Fields.h" +#include + +// Helper macros +#define TMC6200_FIELD_READ(tdef, address, mask, shift) \ + FIELD_GET(tmc6200_readInt(tdef, address), mask, shift) +#define TMC6200_FIELD_UPDATE(tdef, address, mask, shift, value) \ + (tmc6200_writeInt(tdef, address, FIELD_SET(tmc6200_readInt(tdef, address), mask, shift, value))) + +int32_t tmc6200_readInt(uint8_t motor, uint8_t address); +void tmc6200_writeInt(uint8_t motor, uint8_t address, int32_t value); + +#endif /* TMC_IC_TMC6630_H_ */ diff --git a/tmc/ic/TMC6200/TMC6200_Constants.h b/tmc/ic/TMC6200/TMC6200_Constants.h new file mode 100644 index 000000000..049302f4c --- /dev/null +++ b/tmc/ic/TMC6200/TMC6200_Constants.h @@ -0,0 +1,18 @@ +/* + * TMC6200_Constants.h + * + * Created on: 26.10.2018 + * Author: LK + */ + +#ifndef TMC_IC_TMC6200_TMC6200_CONSTANTS_H_ +#define TMC_IC_TMC6200_TMC6200_CONSTANTS_H_ + + +#define TMC6200_MOTORS 1 +#define TMC6200_WRITE_BIT 0x80 +#define TMC6200_ADDRESS_MASK 0x7F +#define TMC6200_MAX_VELOCITY 8388096 +#define TMC6200_MAX_ACCELERATION u16_MAX + +#endif /* TMC_IC_TMC6200_TMC6200_CONSTANTS_H_ */ diff --git a/tmc/ic/TMC6200/TMC6200_Fields.h b/tmc/ic/TMC6200/TMC6200_Fields.h new file mode 100644 index 000000000..50f578333 --- /dev/null +++ b/tmc/ic/TMC6200/TMC6200_Fields.h @@ -0,0 +1,107 @@ +/* + * TMC6200_Fields.h + * Author: LK + * Generated by MaskShiftConverter (unchecked) + */ + +#ifndef TMC6200_FIELDS_H +#define TMC6200_FIELDS_H + +#define TMC6200_DISABLE_MASK 0x01 // GCONF // +#define TMC6200_DISABLE_SHIFT 0 // +#define TMC6200_SINGLELINE_MASK 0x02 // GCONF // 0: Individual, 1: Combined LS/HS control +#define TMC6200_SINGLELINE_SHIFT 1 // 0: Individual, 1: Combined LS/HS control +#define TMC6200_FAULTDIRECT_MASK 0x04 // GCONF // +#define TMC6200_FAULTDIRECT_SHIFT 2 // +#define TMC6200_UNUSED_MASK 0x08 // GCONF // +#define TMC6200_UNUSED_SHIFT 3 // +#define TMC6200_AMPLIFICATION_MASK 0x30 // GCONF // Amplification of current amplifier 0: 5*, 1: 10*, 3:20* +#define TMC6200_AMPLIFICATION_SHIFT 4 // Amplification of current amplifier 0: 5*, 1: 10*, 3:20* +#define TMC6200_CURRENT_ZERO_MASK 0x40 // GCONF // Current amplifier off +#define TMC6200_CURRENT_ZERO_SHIFT 6 // Current amplifier off +#define TMC6200_TEST_MODE_MASK 0x80 // GCONF // +#define TMC6200_TEST_MODE_SHIFT 7 // +#define TMC6200_RESET_MASK 0x01 // GSTAT // reset +#define TMC6200_RESET_SHIFT 0 // reset +#define TMC6200_DRV_OTPW_MASK 0x02 // GSTAT // drv_otpw +#define TMC6200_DRV_OTPW_SHIFT 1 // drv_otpw +#define TMC6200_DRV_OT_MASK 0x04 // GSTAT // drv_ot +#define TMC6200_DRV_OT_SHIFT 2 // drv_ot +#define TMC6200_UV_CP_MASK 0x08 // GSTAT // uv_cp +#define TMC6200_UV_CP_SHIFT 3 // uv_cp +#define TMC6200_SHORTDET_U_MASK 0x10 // GSTAT // shortdet_u +#define TMC6200_SHORTDET_U_SHIFT 4 // shortdet_u +#define TMC6200_S2VSU_MASK 0x40 // GSTAT // short to VS U +#define TMC6200_S2VSU_SHIFT 6 // short to VS U +#define TMC6200_SHORTDET_V_MASK 0x100 // GSTAT // shortdet_v +#define TMC6200_SHORTDET_V_SHIFT 8 // shortdet_v +#define TMC6200_S2GV_MASK 0x200 // GSTAT // short to gnd V +#define TMC6200_S2GV_SHIFT 9 // short to gnd V +#define TMC6200_S2VSV_MASK 0x400 // GSTAT // short to VS V +#define TMC6200_S2VSV_SHIFT 10 // short to VS V +#define TMC6200_SHORTDET_W_MASK 0x1000 // GSTAT // shortdet_W +#define TMC6200_SHORTDET_W_SHIFT 12 // shortdet_W +#define TMC6200_S2VSW_MASK 0x4000 // GSTAT // short to VS W +#define TMC6200_S2VSW_SHIFT 14 // short to VS W +#define TMC6200_UL_MASK 0x01 // IOIN / OUTPUT // UL +#define TMC6200_UL_SHIFT 0 // UL +#define TMC6200_UH_MASK 0x02 // IOIN / OUTPUT // UH +#define TMC6200_UH_SHIFT 1 // UH +#define TMC6200_VL_MASK 0x04 // IOIN / OUTPUT // VL +#define TMC6200_VL_SHIFT 2 // VL +#define TMC6200_VH_MASK 0x08 // IOIN / OUTPUT // VH +#define TMC6200_VH_SHIFT 3 // VH +#define TMC6200_WL_MASK 0x10 // IOIN / OUTPUT // WH +#define TMC6200_WL_SHIFT 4 // WH +#define TMC6200_WH_MASK 0x20 // IOIN / OUTPUT // WH +#define TMC6200_WH_SHIFT 5 // WH +#define TMC6200_DRV_EN_MASK 0x40 // IOIN / OUTPUT // DRV_EN +#define TMC6200_DRV_EN_SHIFT 6 // DRV_EN +#define TMC6200_OTPW_MASK 0x100 // IOIN / OUTPUT // Overtemp prewarning +#define TMC6200_OTPW_SHIFT 8 // Overtemp prewarning +#define TMC6200_OT136C_MASK 0x200 // IOIN / OUTPUT // Overtemp 136°C +#define TMC6200_OT136C_SHIFT 9 // Overtemp 136°C +#define TMC6200_OT143C_MASK 0x400 // IOIN / OUTPUT // Overtemp 143°C +#define TMC6200_OT143C_SHIFT 10 // Overtemp 143°C +#define TMC6200_OT150C_MASK 0x800 // IOIN / OUTPUT // Overtemp 150°C +#define TMC6200_OT150C_SHIFT 11 // Overtemp 150°C +#define TMC6200_VERSION_MASK 0xFF000000 // IOIN / OUTPUT // VERSION: 0x10=first version of the IC; Identical numbers mean full digital compatibility. +#define TMC6200_VERSION_SHIFT 24 // VERSION: 0x10=first version of the IC; Identical numbers mean full digital compatibility. +#define TMC6200_OTPBIT_MASK 0x07 // OTP_PROG // Selection of OTP bit to be programmed to the selected byte location (n=0..7: programs bit n to a logic 1) +#define TMC6200_OTPBIT_SHIFT 0 // Selection of OTP bit to be programmed to the selected byte location (n=0..7: programs bit n to a logic 1) +#define TMC6200_OTPBYTE_MASK 0x30 // OTP_PROG // Set to 00 +#define TMC6200_OTPBYTE_SHIFT 4 // Set to 00 +#define TMC6200_OTPMAGIC_MASK 0xFF00 // OTP_PROG // Set to 0xbd to enable programming. A programming time of minimum 10ms per bit is recommended (check by reading OTP_READ). +#define TMC6200_OTPMAGIC_SHIFT 8 // Set to 0xbd to enable programming. A programming time of minimum 10ms per bit is recommended (check by reading OTP_READ). +#define TMC6200_OTP_BBM_MASK 0xC0 // OTP_READ // Reset default for BBM time, 0: 4 clocks, 1: 1 clocks, 2: 2 clocks, 3: 3 clocks +#define TMC6200_OTP_BBM_SHIFT 6 // Reset default for BBM time, 0: 4 clocks, 1: 1 clocks, 2: 2 clocks, 3: 3 clocks +#define TMC6200_OTP_S2_LEVEL_MASK 0x20 // OTP_READ // Reset default for Short detection Levels +#define TMC6200_OTP_S2_LEVEL_SHIFT 5 // Reset default for Short detection Levels +#define TMC6200_OTP_FCLKTRIM_MASK 0x1F // OTP_READ // Reset default for FCLKTRIM 0: lowest frequency setting 31: highest frequency setting Attention: This value is pre-programmed by factory clock trimming to the default clock frequency of 24MHz and differs between individual ICs! It should not be altered. +#define TMC6200_OTP_FCLKTRIM_SHIFT 0 // Reset default for FCLKTRIM 0: lowest frequency setting 31: highest frequency setting Attention: This value is pre-programmed by factory clock trimming to the default clock frequency of 24MHz and differs between individual ICs! It should not be altered. +#define TMC6200_FCLKTRIM_MASK 0x1F // FACTORY_CONF // FCLKTRIM (Reset default: OTP) 31: Lowest to highest clock frequency. Check at charge pump output. The frequency span is not guaranteed, but it is tested, that tuning to 24MHz internal clock is possible. The devices come preset to 24MHz clock frequency by OTP programming. +#define TMC6200_FCLKTRIM_SHIFT 0 // FCLKTRIM (Reset default: OTP) 31: Lowest to highest clock frequency. Check at charge pump output. The frequency span is not guaranteed, but it is tested, that tuning to 24MHz internal clock is possible. The devices come preset to 24MHz clock frequency by OTP programming. +#define TMC6200_S2VS_LEVEL_MASK 0x0F // SHORT_CONF // Short to VS detector level (15= lowest sensitivity) (Reset Default: OTP 6 or 12) +#define TMC6200_S2VS_LEVEL_SHIFT 0 // Short to VS detector level (15= lowest sensitivity) (Reset Default: OTP 6 or 12) +#define TMC6200_S2GND_LEVEL_MASK 0xF00 // SHORT_CONF // Short to GND detector level (15= lowest sensitivity) (Reset Default: OTP 6 or 12) +#define TMC6200_S2GND_LEVEL_SHIFT 8 // Short to GND detector level (15= lowest sensitivity) (Reset Default: OTP 6 or 12) +#define TMC6200_SHORTFILTER_MASK 0x30000 // SHORT_CONF // Spike filtering bandwidth for short detection (0=lowest) (Reset Default = %01) +#define TMC6200_SHORTFILTER_SHIFT 16 // Spike filtering bandwidth for short detection (0=lowest) (Reset Default = %01) +#define TMC6200_SHORTDELAY_MASK 0x100000 // SHORT_CONF // Detector delay (0=750ns, 1=1500ns) (Reset Default = 0) +#define TMC6200_SHORTDELAY_SHIFT 20 // Detector delay (0=750ns, 1=1500ns) (Reset Default = 0) +#define TMC6200_RETRY_MASK 0x3000000 // SHORT_CONF // 0: Half bridge disabled after first short detection, 1..3: Half bridge re-enabled in next chopper cycles 1 time to 3 times. With retry, the short-counter is decreased once each 256 chopper cycles per coil, unless the upper limit has been reached. (Reset Default = %10) +#define TMC6200_RETRY_SHIFT 24 // 0: Half bridge disabled after first short detection, 1..3: Half bridge re-enabled in next chopper cycles 1 time to 3 times. With retry, the short-counter is decreased once each 256 chopper cycles per coil, unless the upper limit has been reached. (Reset Default = %10) +#define TMC6200_PROTECT_PARALLEL_MASK 0x10000000 // SHORT_CONF // 0: Only the detected half bridge driver becomes shut down upon final short detection, 1: All half bridge drivers become shut down upon final short detection (Reset Default = 1) +#define TMC6200_PROTECT_PARALLEL_SHIFT 28 // 0: Only the detected half bridge driver becomes shut down upon final short detection, 1: All half bridge drivers become shut down upon final short detection (Reset Default = 1) +#define TMC6200_DISABLE_S2G_MASK 0x20000000 // SHORT_CONF // Disable Short to GND protection +#define TMC6200_DISABLE_S2G_SHIFT 29 // Disable Short to GND protection +#define TMC6200_DISABLE_S2VS_MASK 0x40000000 // SHORT_CONF // Disable Short to VS protection +#define TMC6200_DISABLE_S2VS_SHIFT 30 // Disable Short to VS protection +#define TMC6200_BBMCLKS_MASK 0x0F // DRV_CONF // Digital BBM time in multiple of 1 clock. The longer setting rules (BBMTIME vs. BBMCLKS). (Reset Default: OTP 1 to 4) +#define TMC6200_BBMCLKS_SHIFT 0 // Digital BBM time in multiple of 1 clock. The longer setting rules (BBMTIME vs. BBMCLKS). (Reset Default: OTP 1 to 4) +#define TMC6200_OTSELECT_MASK 0x30000 // DRV_CONF // Selection of over temperature level. 00: 150°C, 01: 143°C, 10: 136°C, 11: 120°C (Reset Default = %00) +#define TMC6200_OTSELECT_SHIFT 16 // Selection of over temperature level. 00: 150°C, 01: 143°C, 10: 136°C, 11: 120°C (Reset Default = %00) +#define TMC6200_DRVSTRENGTH_MASK 0xC0000 // DRV_CONF // Selection of gate driver current. 00: weak, 01: weak+TC (medium at > 120°C), 10: medium, 11: strong (Reset Default = %10) +#define TMC6200_DRVSTRENGTH_SHIFT 18 // Selection of gate driver current. 00: weak, 01: weak+TC (medium at > 120°C), 10: medium, 11: strong (Reset Default = %10) + +#endif /* TMC6200_FIELDS_H */ diff --git a/tmc/ic/TMC6200/TMC6200_Register.h b/tmc/ic/TMC6200/TMC6200_Register.h new file mode 100644 index 000000000..5f0495012 --- /dev/null +++ b/tmc/ic/TMC6200/TMC6200_Register.h @@ -0,0 +1,22 @@ +/* +* TMC6200_Register.h +* +* Created on: 14.03.2018 +* Author: ED +*/ + +#ifndef TMC6200_REGISTER_H +#define TMC6200_REGISTER_H + + // ===== TMC6200 register set ===== + + #define TMC6200_GCONF 0x00 + #define TMC6200_GSTAT 0x01 + #define TMC6200_IOIN_OUTPUT 0x04 + #define TMC6200_OTP_PROG 0x06 + #define TMC6200_OTP_READ 0x07 + #define TMC6200_FACTORY_CONF 0x08 + #define TMC6200_SHORT_CONF 0x09 + #define TMC6200_DRV_CONF 0x0A + +#endif /* TMC6200_REGISTER_H */ diff --git a/tmc/tmc.mk b/tmc/tmc.mk new file mode 100644 index 000000000..4d173f091 --- /dev/null +++ b/tmc/tmc.mk @@ -0,0 +1,3 @@ +TMCSRC = tmc/ic/TMC6200/TMC6200.c + +TMCINC = tmc/ic/TMC6200