Merge branch 'devel' into Endstops

This commit is contained in:
Unknown
2018-12-06 23:37:04 -05:00
68 changed files with 952 additions and 7419 deletions
+27 -2
View File
@@ -1,8 +1,34 @@
# Unreleased Features
Please add a note of your changes below this heading if you make a Pull Request.
# Unreleased
### Added
* `dump_errors()` utility function in odrivetool to dump, decode and optionally clear errors.
# Releases
## [0.4.7] - 2018-11-28
### Added
* Overspeed fault
* Current sense saturation fault.
* Supress startup transients by sampling encoder estimate into position setpoint when entering closed loop control.
* Make step dir gpio pins configurable.
* Configuration variable `encoder.config.zero_count_on_find_idx`, true by default. Set to false to leave the initial encoder count to be where the axis was at boot.
* Circular position setpoint mode: position setpoints wrapped [0, cpr). Useful for infinite incremental position control.
* Velocity setpoint ramping. Use velocity control mode, and set `controller.vel_ramp_enable` to true. This will ramp `controller.vel_setpoint` towards `controller.vel_ramp_target` at a ramp rate of `controller.config.vel_ramp_rate`.
### Changed
* Increased switching frequency from around 8kHz to 24kHz. Control loops still run at 8kHz.
* Renamed `axis.enable_step_dir` to `axis.step_dir_active`
* New process for working with STM32CubeMX.
### Fixed
* Would get ERROR_CONTROL_DEADLINE_MISSED along with every ERROR_PHASE_RESISTANCE_OUT_OF_RANGE.
* ODrive tool can now run interactive nested scripts with "%run -i script.py"
## [0.4.6] - 2018-10-07
### Fixed
* Broken printing of floats on ascii protocol
## [0.4.5] - 2018-10-06
### Added
* **Trapezoidal Trajectory Planner**
* Hook to execute protocol property written callback
@@ -24,7 +50,6 @@ Please add a note of your changes below this heading if you make a Pull Request.
* An issue where the axis state machine would jump in and out of idle when there is an error
* There is a [bug](https://github.com/ARM-software/CMSIS_5/issues/267) in the arm fast math library, which gives spikes in the output of arm_cos_f32 for input values close to -pi/2. We fixed the bug locally, and hence are using "our_arm_cos_f32".
# Releases
## [0.4.4] - 2018-09-18
### Fixed
* Serious reliability issue with USB communication where packets on Native and the CDC interface would collide with each other.
@@ -1,41 +0,0 @@
From b7ea3f500fbfc187a0a7112282ae6b1eee4555d0 Mon Sep 17 00:00:00 2001
From: Samuel Sadok <samuel.sadok@bluewin.ch>
Date: Tue, 13 Mar 2018 20:05:07 -0700
Subject: [PATCH] display correct ODrive version in USB descriptor
---
Firmware/Board/v3/Src/usbd_desc.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/Firmware/Board/v3/Src/usbd_desc.c b/Firmware/Board/v3/Src/usbd_desc.c
index 94dc49b..37b4302 100644
--- a/Firmware/Board/v3/Src/usbd_desc.c
+++ b/Firmware/Board/v3/Src/usbd_desc.c
@@ -96,7 +96,9 @@
#define USBD_LANGID_STRING 1033
#define USBD_MANUFACTURER_STRING "ODrive Robotics"
#define USBD_PID_FS 0x0D32
-#define USBD_PRODUCT_STRING_FS "ODrive v3.3"
+#define USBD_PRODUCT_XSTR(s) USBD_PRODUCT_STR(s)
+#define USBD_PRODUCT_STR(s) #s
+#define USBD_PRODUCT_STRING_FS ODrive version HW_VERSION_MAJOR.HW_VERSION_MINOR
#define USBD_SERIALNUMBER_STRING_FS "000000000001"
#define USBD_CONFIGURATION_STRING_FS "CDC Config"
#define USBD_INTERFACE_STRING_FS "CDC Interface"
@@ -299,11 +301,11 @@ uint8_t * USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length
{
if(speed == 0)
{
- USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length);
+ USBD_GetString((uint8_t *)USBD_PRODUCT_XSTR(USBD_PRODUCT_STRING_FS), USBD_StrDesc, length);
}
else
{
- USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length);
+ USBD_GetString((uint8_t *)USBD_PRODUCT_XSTR(USBD_PRODUCT_STRING_FS), USBD_StrDesc, length);
}
return USBD_StrDesc;
}
--
2.16.2
@@ -1,32 +0,0 @@
From 0867a92f742b312a0ebaafe94cade6f57be22170 Mon Sep 17 00:00:00 2001
From: Samuel Sadok <samuel.sadok@bluewin.ch>
Date: Mon, 12 Mar 2018 23:49:32 -0700
Subject: [PATCH] expose correct serial number on USB
---
Firmware/Board/v3/Src/usbd_desc.c | 9 +++++++++-------
1 file changed, 1 insertions(+), 8 deletions(-)
diff --git a/Firmware/Board/v3/Src/usbd_desc.c b/Firmware/Board/v3/Src/usbd_desc.c
index b9c7bd0..94dc49b 100644
--- a/Firmware/Board/v3/Src/usbd_desc.c
+++ b/Firmware/Board/v3/Src/usbd_desc.c
@@ -327,14 +327,7 @@ uint8_t * USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *l
*/
uint8_t * USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
- if(speed == USBD_SPEED_HIGH)
- {
- USBD_GetString((uint8_t *)USBD_SERIALNUMBER_STRING_FS, USBD_StrDesc, length);
- }
- else
- {
- USBD_GetString((uint8_t *)USBD_SERIALNUMBER_STRING_FS, USBD_StrDesc, length);
- }
+ USBD_GetString ((uint8_t *)serial_number_str, USBD_StrDesc, length);
return USBD_StrDesc;
}
--
2.16.2
@@ -1,46 +0,0 @@
From 49353ccb7023c02c2bc6e3b6f14fac02a13fe599 Mon Sep 17 00:00:00 2001
From: Samuel Sadok <samuel.sadok@bluewin.ch>
Date: Mon, 26 Feb 2018 14:55:17 -0800
Subject: [PATCH] fix return type of osSemaphoreWait
---
.../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c | 6 +++---
.../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h | 6 +++---
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c
index d0e0fd7..e764cbc 100644
--- a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c
+++ b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c
@@ -816,10 +816,10 @@ osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t
* @brief Wait until a Semaphore token becomes available
* @param semaphore_id semaphore object referenced with \ref osSemaphore.
* @param millisec timeout value or 0 in case of no time-out.
-* @retval number of available tokens, or -1 in case of incorrect parameters.
+* @retval status code that indicates the execution status of the function.
* @note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS.
*/
-int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec)
+osStatus osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec)
{
TickType_t ticks;
portBASE_TYPE taskWoken = pdFALSE;
diff --git a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h
index 15e25b9..5223f8e 100644
--- a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h
+++ b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h
@@ -719,9 +719,9 @@ osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t
/// Wait until a Semaphore token becomes available.
/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate.
/// \param[in] millisec timeout value or 0 in case of no time-out.
-/// \return number of available tokens, or -1 in case of incorrect parameters.
+/// \return status code that indicates the execution status of the function.
/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS.
-int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec);
+osStatus osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec);
/// Release a Semaphore token.
/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate.
--
2.16.1
@@ -1,35 +0,0 @@
From 965f7f2c80e30d7a66dcac7abaa9bdc371d9ea51 Mon Sep 17 00:00:00 2001
From: Samuel Sadok <samuel.sadok@bluewin.ch>
Date: Mon, 26 Feb 2018 14:53:52 -0800
Subject: [PATCH] release sem_usb_tx in usbd_cdc.c
---
.../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c b/Firmware/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c
index b2ca5f1..6ae33e8 100644
--- a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c
+++ b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c
@@ -62,7 +62,8 @@
#include "usbd_cdc.h"
#include "usbd_desc.h"
#include "usbd_ctlreq.h"
-
+#include <cmsis_os.h>
+#include <freertos_vars.h>
/** @addtogroup STM32_USB_DEVICE_LIBRARY
* @{
@@ -669,7 +670,7 @@ static uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum)
{
hcdc->TxState = 0;
-
+ osSemaphoreRelease(sem_usb_tx);
return USBD_OK;
}
else
--
2.16.1
File diff suppressed because it is too large Load Diff
@@ -1,64 +0,0 @@
From 510ead2b159e1d8116e5241066c54a7bf8b7bfbe Mon Sep 17 00:00:00 2001
From: Samuel Sadok <samuel.sadok@bluewin.ch>
Date: Mon, 26 Mar 2018 15:29:44 -0700
Subject: [PATCH] FreeRTOS constness fixes
- make thread names const char *
- make thread argument non-const void*
---
.../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h | 6 +++---
Firmware/Board/v3/Src/freertos.c | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h
index 09cdf27..754be24 100644
--- a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h
+++ b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h
@@ -270,11 +270,11 @@ typedef enum {
/// Entry point of a thread.
/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS.
-typedef void (*os_pthread) (void const *argument);
+typedef void (*os_pthread) (void *argument);
/// Entry point of a timer call back function.
/// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS.
-typedef void (*os_ptimer) (void const *argument);
+typedef void (*os_ptimer) (void *argument);
// >>> the following data type definitions may shall adapted towards a specific RTOS
@@ -323,7 +323,7 @@ typedef StaticQueue_t osStaticMessageQDef_t;
/// Thread Definition structure contains startup information of a thread.
/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS.
typedef struct os_thread_def {
- char *name; ///< Thread name
+ const char *name; ///< Thread name
os_pthread pthread; ///< start address of thread function
osPriority tpriority; ///< initial thread priority
uint32_t instances; ///< maximum number of instances of that thread function
diff --git a/Firmware/Board/v3/Src/freertos.c b/Firmware/Board/v3/Src/freertos.c
index 6eaea82..b247994 100644
--- a/Firmware/Board/v3/Src/freertos.c
+++ b/Firmware/Board/v3/Src/freertos.c
@@ -75,7 +75,7 @@ uint8_t ucHeap[configTOTAL_HEAP_SIZE];
/* USER CODE END Variables */
/* Function prototypes -------------------------------------------------------*/
-void StartDefaultTask(void const * argument);
+void StartDefaultTask(void * argument);
extern void MX_USB_DEVICE_Init(void);
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
@@ -147,7 +147,7 @@ void MX_FREERTOS_Init(void) {
}
/* StartDefaultTask function */
-void StartDefaultTask(void const * argument)
+void StartDefaultTask(void * argument)
{
/* init code for USB_DEVICE */
MX_USB_DEVICE_Init();
--
2.16.2
@@ -1,33 +0,0 @@
From ab5ca860b3729d76a9c43c485776147ab69d2342 Mon Sep 17 00:00:00 2001
From: Samuel Sadok <samuel.sadok@bluewin.ch>
Date: Mon, 26 Mar 2018 19:02:45 -0700
Subject: [PATCH] disable IRQ for DMA2_Stream0
This DMA stream is used to read values from ADC1
while ADC1 cycles through it's sequence of input
channels. No interrupts are required to make
this work.
---
Firmware/Board/v3/Src/dma.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/Firmware/Board/v3/Src/dma.c b/Firmware/Board/v3/Src/dma.c
index 55d5e03..3de873a 100644
--- a/Firmware/Board/v3/Src/dma.c
+++ b/Firmware/Board/v3/Src/dma.c
@@ -78,8 +78,10 @@ void MX_DMA_Init(void)
HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);
/* DMA2_Stream0_IRQn interrupt configuration */
- HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 5, 0);
- HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
+ // Dear STM, no we _don't_ want to fire an interrupt for this DMA
+ // (it's not possible to deselect this in CubeMX)
+ //HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 5, 0);
+ //HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}
--
2.16.2
@@ -70,6 +70,9 @@ typedef enum
} HAL_LockTypeDef;
/* Exported macro ------------------------------------------------------------*/
#define UNUSED(X) (void)X /* To avoid gcc/g++ warnings */
#define HAL_MAX_DELAY 0xFFFFFFFFU
#define HAL_IS_BIT_SET(REG, BIT) (((REG) & (BIT)) != RESET)
@@ -79,9 +82,7 @@ typedef enum
do{ \
(__HANDLE__)->__PPP_DMA_FIELD__ = &(__DMA_HANDLE__); \
(__DMA_HANDLE__).Parent = (__HANDLE__); \
} while(0)
#define UNUSED(x) ((void)(x))
} while(0U)
/** @brief Reset the Handle's State field.
* @param __HANDLE__ specifies the Peripheral Handle.
@@ -135,7 +136,7 @@ typedef enum
/* Macro to get variable aligned on 4-bytes, for __ICCARM__ the directive "#pragma data_alignment=4" must be used instead */
#if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */
#ifndef __ALIGN_END
#define __ALIGN_END __attribute__ ((aligned (4)))
#define __ALIGN_END __attribute__ ((aligned (4)))
#endif /* __ALIGN_END */
#ifndef __ALIGN_BEGIN
#define __ALIGN_BEGIN
@@ -146,7 +147,7 @@ typedef enum
#endif /* __ALIGN_END */
#ifndef __ALIGN_BEGIN
#if defined (__CC_ARM) /* ARM Compiler */
#define __ALIGN_BEGIN __align(4)
#define __ALIGN_BEGIN __align(4)
#elif defined (__ICCARM__) /* IAR Compiler */
#define __ALIGN_BEGIN
#endif /* __CC_ARM */
@@ -167,14 +168,14 @@ typedef enum
Available memory areas are declared in the 'Target' tab of the 'Options for Target'
dialog.
*/
#define __RAM_FUNC HAL_StatusTypeDef
#define __RAM_FUNC
#elif defined ( __ICCARM__ )
/* ICCARM Compiler
---------------
RAM functions are defined using a specific toolchain keyword "__ramfunc".
*/
#define __RAM_FUNC __ramfunc HAL_StatusTypeDef
#define __RAM_FUNC __ramfunc
#elif defined ( __GNUC__ )
/* GNU Compiler
@@ -182,7 +183,7 @@ typedef enum
RAM functions are defined using a specific toolchain attribute
"__attribute__((section(".RamFunc")))".
*/
#define __RAM_FUNC HAL_StatusTypeDef __attribute__((section(".RamFunc")))
#define __RAM_FUNC __attribute__((section(".RamFunc")))
#endif
@@ -64,10 +64,10 @@
/** @addtogroup FLASH_RAMFUNC_Exported_Functions_Group1
* @{
*/
__RAM_FUNC HAL_FLASHEx_StopFlashInterfaceClk(void);
__RAM_FUNC HAL_FLASHEx_StartFlashInterfaceClk(void);
__RAM_FUNC HAL_FLASHEx_EnableFlashSleepMode(void);
__RAM_FUNC HAL_FLASHEx_DisableFlashSleepMode(void);
__RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_StopFlashInterfaceClk(void);
__RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_StartFlashInterfaceClk(void);
__RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_EnableFlashSleepMode(void);
__RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_DisableFlashSleepMode(void);
/**
* @}
*/
@@ -66,11 +66,11 @@
* @{
*/
/**
* @brief STM32F4xx HAL Driver version number V1.7.3
* @brief STM32F4xx HAL Driver version number V1.7.4
*/
#define __STM32F4xx_HAL_VERSION_MAIN (0x01U) /*!< [31:24] main version */
#define __STM32F4xx_HAL_VERSION_SUB1 (0x07U) /*!< [23:16] sub1 version */
#define __STM32F4xx_HAL_VERSION_SUB2 (0x03U) /*!< [15:8] sub2 version */
#define __STM32F4xx_HAL_VERSION_SUB2 (0x04U) /*!< [15:8] sub2 version */
#define __STM32F4xx_HAL_VERSION_RC (0x00U) /*!< [7:0] release candidate */
#define __STM32F4xx_HAL_VERSION ((__STM32F4xx_HAL_VERSION_MAIN << 24U)\
|(__STM32F4xx_HAL_VERSION_SUB1 << 16U)\
@@ -107,9 +107,9 @@
* @note This mode is only available for STM32F41xxx/STM32F446xx devices.
* @note This mode couldn't be set while executing with the flash itself.
* It should be done with specific routine executed from RAM.
* @retval None
* @retval HAL status
*/
__RAM_FUNC HAL_FLASHEx_StopFlashInterfaceClk(void)
__RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_StopFlashInterfaceClk(void)
{
/* Enable Power ctrl clock */
__HAL_RCC_PWR_CLK_ENABLE();
@@ -124,9 +124,9 @@ __RAM_FUNC HAL_FLASHEx_StopFlashInterfaceClk(void)
* @note This mode is only available for STM32F411xx/STM32F446xx devices.
* @note This mode couldn't be set while executing with the flash itself.
* It should be done with specific routine executed from RAM.
* @retval None
* @retval HAL status
*/
__RAM_FUNC HAL_FLASHEx_StartFlashInterfaceClk(void)
__RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_StartFlashInterfaceClk(void)
{
/* Enable Power ctrl clock */
__HAL_RCC_PWR_CLK_ENABLE();
@@ -141,9 +141,9 @@ __RAM_FUNC HAL_FLASHEx_StartFlashInterfaceClk(void)
* @note This mode is only available for STM32F41xxx/STM32F446xx devices.
* @note This mode could n't be set while executing with the flash itself.
* It should be done with specific routine executed from RAM.
* @retval None
* @retval HAL status
*/
__RAM_FUNC HAL_FLASHEx_EnableFlashSleepMode(void)
__RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_EnableFlashSleepMode(void)
{
/* Enable Power ctrl clock */
__HAL_RCC_PWR_CLK_ENABLE();
@@ -158,9 +158,9 @@ __RAM_FUNC HAL_FLASHEx_EnableFlashSleepMode(void)
* @note This mode is only available for STM32F41xxx/STM32F446xx devices.
* @note This mode couldn't be set while executing with the flash itself.
* It should be done with specific routine executed from RAM.
* @retval None
* @retval HAL status
*/
__RAM_FUNC HAL_FLASHEx_DisableFlashSleepMode(void)
__RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_DisableFlashSleepMode(void)
{
/* Enable Power ctrl clock */
__HAL_RCC_PWR_CLK_ENABLE();
+2 -2
View File
@@ -89,7 +89,6 @@
/* Ensure stdint is only used by the compiler, and not the assembler. */
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
#include <stdint.h>
#include "main.h"
extern uint32_t SystemCoreClock;
#endif
@@ -153,7 +152,7 @@ See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
/* USER CODE BEGIN 1 */
/* USER CODE BEGIN 1 */
#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );}
/* USER CODE END 1 */
@@ -168,6 +167,7 @@ standard names. */
/* USER CODE BEGIN Defines */
/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */
#define configAPPLICATION_ALLOCATED_HEAP 1 // ucHeap allocated in freertos.c
/* USER CODE END Defines */
#endif /* FREERTOS_CONFIG_H */
+4 -4
View File
@@ -67,12 +67,12 @@
/* Private define ------------------------------------------------------------*/
#define TIM_1_8_CLOCK_HZ 168000000
#define TIM_1_8_PERIOD_CLOCKS 10192
#define TIM_1_8_PERIOD_CLOCKS 3500
#define TIM_1_8_DEADTIME_CLOCKS 20
#define TIM_APB1_CLOCK_HZ 84000000
#define TIM_APB1_PERIOD_CLOCKS 4096
#define TIM_APB1_DEADTIME_CLOCKS 40
#define configAPPLICATION_ALLOCATED_HEAP 1
#define TIM_1_8_RCR 2
#define M0_nCS_Pin GPIO_PIN_13
#define M0_nCS_GPIO_Port GPIOC
@@ -168,8 +168,8 @@
//TODO: make this come automatically out of CubeMX somehow
#define TIM_TIME_BASE TIM14
#define CURRENT_MEAS_PERIOD ((float)(2*TIM_1_8_PERIOD_CLOCKS)/(float)TIM_1_8_CLOCK_HZ)
#define CURRENT_MEAS_HZ (TIM_1_8_CLOCK_HZ/(2*TIM_1_8_PERIOD_CLOCKS))
#define CURRENT_MEAS_PERIOD ( (float)2*TIM_1_8_PERIOD_CLOCKS*(TIM_1_8_RCR+1) / (float)TIM_1_8_CLOCK_HZ )
#define CURRENT_MEAS_HZ ( (float)(TIM_1_8_CLOCK_HZ) / (float)(2*TIM_1_8_PERIOD_CLOCKS*(TIM_1_8_RCR+1)) )
#if HW_VERSION_VOLTAGE == 48
#define VBUS_S_DIVIDER_RATIO 19.0f
@@ -1,12 +1,12 @@
/* Private define ------------------------------------------------------------*/
#define TIM_1_8_CLOCK_HZ 168000000
#define TIM_1_8_PERIOD_CLOCKS 10192
#define TIM_1_8_PERIOD_CLOCKS 3500
#define TIM_1_8_DEADTIME_CLOCKS 20
#define TIM_APB1_CLOCK_HZ 84000000
#define TIM_APB1_PERIOD_CLOCKS 4096
#define TIM_APB1_DEADTIME_CLOCKS 40
#define configAPPLICATION_ALLOCATED_HEAP 1
#define TIM_1_8_RCR 2
#define M0_nCS_Pin GPIO_PIN_13
#define M0_nCS_GPIO_Port GPIOC
@@ -1,12 +1,12 @@
/* Private define ------------------------------------------------------------*/
#define TIM_1_8_CLOCK_HZ 168000000
#define TIM_1_8_PERIOD_CLOCKS 10192
#define TIM_1_8_PERIOD_CLOCKS 3500
#define TIM_1_8_DEADTIME_CLOCKS 20
#define TIM_APB1_CLOCK_HZ 84000000
#define TIM_APB1_PERIOD_CLOCKS 4096
#define TIM_APB1_DEADTIME_CLOCKS 40
#define configAPPLICATION_ALLOCATED_HEAP 1
#define TIM_1_8_RCR 2
#define M0_nCS_Pin GPIO_PIN_13
#define M0_nCS_GPIO_Port GPIOC
@@ -91,6 +91,7 @@
/* #define HAL_SPDIFRX_MODULE_ENABLED */
/* #define HAL_DFSDM_MODULE_ENABLED */
/* #define HAL_LPTIM_MODULE_ENABLED */
/* #define HAL_EXTI_MODULE_ENABLED */
#define HAL_GPIO_MODULE_ENABLED
#define HAL_DMA_MODULE_ENABLED
#define HAL_RCC_MODULE_ENABLED
@@ -244,6 +245,10 @@
#include "stm32f4xx_hal_rcc.h"
#endif /* HAL_RCC_MODULE_ENABLED */
#ifdef HAL_EXTI_MODULE_ENABLED
#include "stm32f4xx_hal_exti.h"
#endif /* HAL_EXTI_MODULE_ENABLED */
#ifdef HAL_GPIO_MODULE_ENABLED
#include "stm32f4xx_hal_gpio.h"
#endif /* HAL_GPIO_MODULE_ENABLED */
+3
View File
@@ -54,8 +54,10 @@ void BusFault_Handler(void);
void UsageFault_Handler(void);
void DebugMon_Handler(void);
void SysTick_Handler(void);
void DMA1_Stream0_IRQHandler(void);
void DMA1_Stream2_IRQHandler(void);
void DMA1_Stream4_IRQHandler(void);
void DMA1_Stream5_IRQHandler(void);
void ADC_IRQHandler(void);
void CAN1_TX_IRQHandler(void);
void CAN1_RX0_IRQHandler(void);
@@ -63,6 +65,7 @@ void CAN1_RX1_IRQHandler(void);
void CAN1_SCE_IRQHandler(void);
void TIM8_TRG_COM_TIM14_IRQHandler(void);
void TIM5_IRQHandler(void);
void SPI3_IRQHandler(void);
void UART4_IRQHandler(void);
void OTG_FS_IRQHandler(void);
+4 -3
View File
@@ -67,6 +67,7 @@ extern TIM_HandleTypeDef htim3;
extern TIM_HandleTypeDef htim4;
extern TIM_HandleTypeDef htim5;
extern TIM_HandleTypeDef htim8;
extern TIM_HandleTypeDef htim13;
/* USER CODE BEGIN Private defines */
@@ -80,10 +81,10 @@ void MX_TIM3_Init(void);
void MX_TIM4_Init(void);
void MX_TIM5_Init(void);
void MX_TIM8_Init(void);
void MX_TIM13_Init(void);
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
/* USER CODE BEGIN Prototypes */
void OC4_PWM_Override(TIM_HandleTypeDef* htim);
+1 -1
View File
@@ -89,7 +89,7 @@
* @brief Defines for configuration of the Usb device.
* @{
*/
#define MS_VendorCode 'P'
#define MS_VendorCode 'P'
/*---------- -----------*/
#define USBD_MAX_NUM_INTERFACES 1
@@ -26,7 +26,7 @@
*
*----------------------------------------------------------------------------
*
* Portions Copyright © 2016 STMicroelectronics International N.V. All rights reserved.
* Portions Copyright 2016 STMicroelectronics International N.V. All rights reserved.
* Portions Copyright (c) 2013 ARM LIMITED
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
+53 -16
View File
@@ -76,9 +76,11 @@ ADC3.SamplingTime-7\#ChannelRegularConversion=ADC_SAMPLETIME_3CYCLES
ADC3.SamplingTime-8\#ChannelInjectedConversion=ADC_SAMPLETIME_3CYCLES
ADC3.ScanConvMode=DISABLE
CAN1.AutoWakeUp=ENABLE
CAN1.CalculateTimeBit=2000
CAN1.BS1=CAN_BS1_6TQ
CAN1.BS2=CAN_BS2_5TQ
CAN1.CalculateTimeBit=500
CAN1.CalculateTimeQuantum=166.66666666666669
CAN1.IPParameters=CalculateTimeQuantum,CalculateTimeBit,Prescaler,TimeSeg1,TimeSeg2,AutoWakeUp
CAN1.IPParameters=CalculateTimeQuantum,CalculateTimeBit,Prescaler,TimeSeg1,TimeSeg2,AutoWakeUp,BS1,BS2
CAN1.Prescaler=7
CAN1.TimeSeg1=CAN_BS1_6TQ
CAN1.TimeSeg2=CAN_BS2_5TQ
@@ -95,7 +97,29 @@ Dma.ADC1.2.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlign
Dma.Request0=UART4_RX
Dma.Request1=UART4_TX
Dma.Request2=ADC1
Dma.RequestsNb=3
Dma.Request3=SPI3_TX
Dma.Request4=SPI3_RX
Dma.RequestsNb=5
Dma.SPI3_RX.4.Direction=DMA_PERIPH_TO_MEMORY
Dma.SPI3_RX.4.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.SPI3_RX.4.Instance=DMA1_Stream0
Dma.SPI3_RX.4.MemDataAlignment=DMA_MDATAALIGN_HALFWORD
Dma.SPI3_RX.4.MemInc=DMA_MINC_ENABLE
Dma.SPI3_RX.4.Mode=DMA_NORMAL
Dma.SPI3_RX.4.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD
Dma.SPI3_RX.4.PeriphInc=DMA_PINC_DISABLE
Dma.SPI3_RX.4.Priority=DMA_PRIORITY_MEDIUM
Dma.SPI3_RX.4.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.SPI3_TX.3.Direction=DMA_MEMORY_TO_PERIPH
Dma.SPI3_TX.3.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.SPI3_TX.3.Instance=DMA1_Stream5
Dma.SPI3_TX.3.MemDataAlignment=DMA_MDATAALIGN_HALFWORD
Dma.SPI3_TX.3.MemInc=DMA_MINC_ENABLE
Dma.SPI3_TX.3.Mode=DMA_NORMAL
Dma.SPI3_TX.3.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD
Dma.SPI3_TX.3.PeriphInc=DMA_PINC_DISABLE
Dma.SPI3_TX.3.Priority=DMA_PRIORITY_MEDIUM
Dma.SPI3_TX.3.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.UART4_RX.0.Direction=DMA_PERIPH_TO_MEMORY
Dma.UART4_RX.0.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.UART4_RX.0.Instance=DMA1_Stream2
@@ -135,9 +159,10 @@ Mcu.IP12=TIM3
Mcu.IP13=TIM4
Mcu.IP14=TIM5
Mcu.IP15=TIM8
Mcu.IP16=UART4
Mcu.IP17=USB_DEVICE
Mcu.IP18=USB_OTG_FS
Mcu.IP16=TIM13
Mcu.IP17=UART4
Mcu.IP18=USB_DEVICE
Mcu.IP19=USB_OTG_FS
Mcu.IP2=ADC3
Mcu.IP3=CAN1
Mcu.IP4=DMA
@@ -146,7 +171,7 @@ Mcu.IP6=NVIC
Mcu.IP7=RCC
Mcu.IP8=SPI3
Mcu.IP9=SYS
Mcu.IPNb=19
Mcu.IPNb=20
Mcu.Name=STM32F405RGTx
Mcu.Package=LQFP64
Mcu.Pin0=PC13-ANTI_TAMP
@@ -200,25 +225,28 @@ Mcu.Pin51=VP_FREERTOS_VS_ENABLE
Mcu.Pin52=VP_SYS_VS_tim14
Mcu.Pin53=VP_TIM1_VS_ClockSourceINT
Mcu.Pin54=VP_TIM1_VS_no_output4
Mcu.Pin55=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS
Mcu.Pin55=VP_TIM13_VS_ClockSourceINT
Mcu.Pin56=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS
Mcu.Pin6=PC1
Mcu.Pin7=PC2
Mcu.Pin8=PC3
Mcu.Pin9=PA0-WKUP
Mcu.PinsNb=56
Mcu.PinsNb=57
Mcu.ThirdPartyNb=0
Mcu.UserConstants=TIM_1_8_CLOCK_HZ,168000000;TIM_1_8_PERIOD_CLOCKS,10192;TIM_1_8_DEADTIME_CLOCKS,20;TIM_APB1_CLOCK_HZ,84000000;TIM_APB1_PERIOD_CLOCKS,4096;TIM_APB1_DEADTIME_CLOCKS,40;configAPPLICATION_ALLOCATED_HEAP,1
Mcu.UserConstants=TIM_1_8_CLOCK_HZ,168000000;TIM_1_8_PERIOD_CLOCKS,3500;TIM_1_8_DEADTIME_CLOCKS,20;TIM_APB1_CLOCK_HZ,84000000;TIM_APB1_PERIOD_CLOCKS,4096;TIM_APB1_DEADTIME_CLOCKS,40;TIM_1_8_RCR,2
Mcu.UserName=STM32F405RGTx
MxCube.Version=4.24.0
MxDb.Version=DB.4.0.240
MxCube.Version=4.27.0
MxDb.Version=DB.4.0.270
NVIC.ADC_IRQn=true\:5\:0\:false\:false\:true\:true\:true
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:true
NVIC.CAN1_RX0_IRQn=true\:6\:0\:true\:false\:true\:true\:true
NVIC.CAN1_RX1_IRQn=true\:6\:0\:true\:false\:true\:true\:true
NVIC.CAN1_SCE_IRQn=true\:6\:0\:true\:false\:true\:true\:true
NVIC.CAN1_TX_IRQn=true\:6\:0\:true\:false\:true\:true\:true
NVIC.DMA1_Stream0_IRQn=true\:5\:0\:false\:false\:true\:true\:false
NVIC.DMA1_Stream2_IRQn=true\:5\:0\:false\:false\:true\:true\:true
NVIC.DMA1_Stream4_IRQn=true\:5\:0\:false\:false\:true\:true\:false
NVIC.DMA1_Stream5_IRQn=true\:5\:0\:false\:false\:true\:true\:false
NVIC.DMA2_Stream0_IRQn=true\:5\:0\:false\:false\:false\:true\:false
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:true
@@ -227,6 +255,7 @@ NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:true
NVIC.OTG_FS_IRQn=true\:5\:0\:false\:false\:true\:true\:true
NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:true
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SPI3_IRQn=true\:5\:0\:false\:false\:true\:true\:true
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:true
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:true\:true
NVIC.TIM1_UP_TIM10_IRQn=true\:0\:0\:false\:false\:false\:false\:true
@@ -443,13 +472,15 @@ ProjectManager.CustomerFirmwarePackage=
ProjectManager.DefaultFWLocation=true
ProjectManager.DeletePrevious=true
ProjectManager.DeviceId=STM32F405RGTx
ProjectManager.FirmwarePackage=STM32Cube FW_F4 V1.19.0
ProjectManager.FirmwarePackage=STM32Cube FW_F4 V1.21.0
ProjectManager.FreePins=false
ProjectManager.HalAssertFull=false
ProjectManager.HeapSize=0x3C00
ProjectManager.KeepUserCode=true
ProjectManager.LastFirmware=true
ProjectManager.LibraryCopy=1
ProjectManager.MainLocation=Src
ProjectManager.NoMain=false
ProjectManager.PreviousToolchain=SW4STM32
ProjectManager.ProjectBuild=false
ProjectManager.ProjectFileName=Odrive.ioc
@@ -458,7 +489,7 @@ ProjectManager.StackSize=0x800
ProjectManager.TargetToolchain=Makefile
ProjectManager.ToolChainLocation=
ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-MX_DMA_Init-DMA-false-HAL-true,3-MX_ADC1_Init-ADC1-false-HAL-true,4-MX_ADC2_Init-ADC2-false-HAL-true,5-MX_CAN1_Init-CAN1-false-HAL-true,6-MX_TIM1_Init-TIM1-false-HAL-true,7-MX_TIM8_Init-TIM8-false-HAL-true,8-MX_TIM3_Init-TIM3-false-HAL-true,9-MX_TIM4_Init-TIM4-false-HAL-true,10-MX_SPI3_Init-SPI3-false-HAL-true,11-MX_ADC3_Init-ADC3-false-HAL-true,12-SystemClock_Config-RCC-false-HAL-true,13-MX_TIM2_Init-TIM2-false-HAL-true,14-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-true,15-MX_UART4_Init-UART4-false-HAL-true,16-MX_TIM5_Init-TIM5-false-HAL-true
ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-MX_DMA_Init-DMA-false-HAL-true,3-MX_ADC1_Init-ADC1-false-HAL-true,4-MX_ADC2_Init-ADC2-false-HAL-true,5-MX_CAN1_Init-CAN1-false-HAL-true,6-MX_TIM1_Init-TIM1-false-HAL-true,7-MX_TIM8_Init-TIM8-false-HAL-true,8-MX_TIM3_Init-TIM3-false-HAL-true,9-MX_TIM4_Init-TIM4-false-HAL-true,10-MX_SPI3_Init-SPI3-false-HAL-true,11-MX_ADC3_Init-ADC3-false-HAL-true,12-SystemClock_Config-RCC-false-HAL-true,13-MX_TIM2_Init-TIM2-false-HAL-true,14-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-true,15-MX_UART4_Init-UART4-false-HAL-true,16-MX_TIM5_Init-TIM5-false-HAL-true,17-MX_TIM13_Init-TIM13-false-HAL-true
RCC.48MHZClocksFreq_Value=48000000
RCC.AHBFreq_Value=168000000
RCC.APB1CLKDivider=RCC_HCLK_DIV4
@@ -576,7 +607,7 @@ TIM1.Channel-PWM\ Generation2\ CH2\ CH2N=TIM_CHANNEL_2
TIM1.Channel-PWM\ Generation3\ CH3\ CH3N=TIM_CHANNEL_3
TIM1.CounterMode=TIM_COUNTERMODE_CENTERALIGNED3
TIM1.DeadTime=TIM_1_8_DEADTIME_CLOCKS
TIM1.IPParameters=Channel-PWM Generation2 CH2 CH2N,Channel-PWM Generation3 CH3 CH3N,OCNPolarity_1,OCNPolarity_2,OCNPolarity_3,CounterMode,OCMode_PWM-PWM Generation1 CH1 CH1N,OCMode_PWM-PWM Generation2 CH2 CH2N,OCMode_PWM-PWM Generation3 CH3 CH3N,Period,DeadTime,OffStateRunMode,OffStateIDLEMode,Channel-Output Compare4 No Output,TIM_MasterOutputTrigger,Channel-PWM Generation1 CH1 CH1N
TIM1.IPParameters=Channel-PWM Generation2 CH2 CH2N,Channel-PWM Generation3 CH3 CH3N,OCNPolarity_1,OCNPolarity_2,OCNPolarity_3,CounterMode,OCMode_PWM-PWM Generation1 CH1 CH1N,OCMode_PWM-PWM Generation2 CH2 CH2N,OCMode_PWM-PWM Generation3 CH3 CH3N,Period,DeadTime,OffStateRunMode,OffStateIDLEMode,Channel-Output Compare4 No Output,TIM_MasterOutputTrigger,Channel-PWM Generation1 CH1 CH1N,RepetitionCounter
TIM1.OCMode_PWM-PWM\ Generation1\ CH1\ CH1N=TIM_OCMODE_PWM2
TIM1.OCMode_PWM-PWM\ Generation2\ CH2\ CH2N=TIM_OCMODE_PWM2
TIM1.OCMode_PWM-PWM\ Generation3\ CH3\ CH3N=TIM_OCMODE_PWM2
@@ -586,7 +617,10 @@ TIM1.OCNPolarity_3=TIM_OCNPOLARITY_HIGH
TIM1.OffStateIDLEMode=TIM_OSSI_ENABLE
TIM1.OffStateRunMode=TIM_OSSR_ENABLE
TIM1.Period=TIM_1_8_PERIOD_CLOCKS
TIM1.RepetitionCounter=TIM_1_8_RCR
TIM1.TIM_MasterOutputTrigger=TIM_TRGO_UPDATE
TIM13.IPParameters=Period
TIM13.Period=(2 * TIM_1_8_PERIOD_CLOCKS * (TIM_1_8_RCR+1)) * (TIM_APB1_CLOCK_HZ / TIM_1_8_CLOCK_HZ)
TIM2.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
TIM2.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4
TIM2.CounterMode=TIM_COUNTERMODE_CENTERALIGNED3
@@ -624,13 +658,14 @@ TIM8.Channel-PWM\ Generation2\ CH2\ CH2N=TIM_CHANNEL_2
TIM8.Channel-PWM\ Generation3\ CH3\ CH3N=TIM_CHANNEL_3
TIM8.CounterMode=TIM_COUNTERMODE_CENTERALIGNED3
TIM8.DeadTime=TIM_1_8_DEADTIME_CLOCKS
TIM8.IPParameters=Channel-PWM Generation3 CH3 CH3N,Channel-PWM Generation2 CH2 CH2N,CounterMode,Period,OffStateRunMode,OffStateIDLEMode,DeadTime,OCMode_PWM-PWM Generation1 CH1 CH1N,OCMode_PWM-PWM Generation2 CH2 CH2N,OCMode_PWM-PWM Generation3 CH3 CH3N,Channel-Output Compare4 No Output,TIM_MasterOutputTrigger,Channel-PWM Generation1 CH1 CH1N
TIM8.IPParameters=Channel-PWM Generation3 CH3 CH3N,Channel-PWM Generation2 CH2 CH2N,CounterMode,Period,OffStateRunMode,OffStateIDLEMode,DeadTime,OCMode_PWM-PWM Generation1 CH1 CH1N,OCMode_PWM-PWM Generation2 CH2 CH2N,OCMode_PWM-PWM Generation3 CH3 CH3N,Channel-Output Compare4 No Output,TIM_MasterOutputTrigger,Channel-PWM Generation1 CH1 CH1N,RepetitionCounter
TIM8.OCMode_PWM-PWM\ Generation1\ CH1\ CH1N=TIM_OCMODE_PWM2
TIM8.OCMode_PWM-PWM\ Generation2\ CH2\ CH2N=TIM_OCMODE_PWM2
TIM8.OCMode_PWM-PWM\ Generation3\ CH3\ CH3N=TIM_OCMODE_PWM2
TIM8.OffStateIDLEMode=TIM_OSSI_ENABLE
TIM8.OffStateRunMode=TIM_OSSR_ENABLE
TIM8.Period=TIM_1_8_PERIOD_CLOCKS
TIM8.RepetitionCounter=TIM_1_8_RCR
TIM8.TIM_MasterOutputTrigger=TIM_TRGO_UPDATE
UART4.IPParameters=VirtualMode
UART4.VirtualMode=Asynchronous
@@ -652,6 +687,8 @@ VP_FREERTOS_VS_ENABLE.Mode=Enabled
VP_FREERTOS_VS_ENABLE.Signal=FREERTOS_VS_ENABLE
VP_SYS_VS_tim14.Mode=TIM14
VP_SYS_VS_tim14.Signal=SYS_VS_tim14
VP_TIM13_VS_ClockSourceINT.Mode=Enable_Timer
VP_TIM13_VS_ClockSourceINT.Signal=TIM13_VS_ClockSourceINT
VP_TIM1_VS_ClockSourceINT.Mode=Internal
VP_TIM1_VS_ClockSourceINT.Signal=TIM1_VS_ClockSourceINT
VP_TIM1_VS_no_output4.Mode=Output Compare4 No Output
+3 -2
View File
@@ -134,9 +134,10 @@ SECTIONS
*
* IMPORTANT NOTE!
* If initialized variables will be placed in this section,
* the startup code needs to be modified to copy the init-values.
* the startup code needs to be modified to copy the init-values.
* Oskar: Added NOLOAD to remove this section from .bin outputs
*/
.ccmram :
.ccmram (NOLOAD):
{
. = ALIGN(4);
_sccmram = .; /* create a global symbol at ccmram start */
+6
View File
@@ -71,12 +71,18 @@ void MX_DMA_Init(void)
__HAL_RCC_DMA2_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Stream0_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
/* DMA1_Stream2_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);
/* DMA1_Stream4_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);
/* DMA1_Stream5_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
/* DMA2_Stream0_IRQn interrupt configuration */
// Dear STM, no we _don't_ want to fire an interrupt for this DMA
// (it's not possible to deselect this in CubeMX)
+38 -10
View File
@@ -1,3 +1,4 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name : freertos.c
@@ -45,12 +46,15 @@
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "freertos_vars.h"
#include "usb_device.h"
@@ -58,9 +62,22 @@ extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
int odrive_main(void);
/* USER CODE END Includes */
/* Variables -----------------------------------------------------------------*/
osThreadId defaultTaskHandle;
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
// List of semaphores
osSemaphoreId sem_usb_irq;
@@ -74,17 +91,18 @@ osThreadId usb_irq_thread;
__attribute__((section(".ccmram")))
uint8_t ucHeap[configTOTAL_HEAP_SIZE];
/* USER CODE END Variables */
osThreadId defaultTaskHandle;
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
/* USER CODE END FunctionPrototypes */
/* Function prototypes -------------------------------------------------------*/
void StartDefaultTask(void * argument);
extern void MX_USB_DEVICE_Init(void);
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
/* USER CODE BEGIN FunctionPrototypes */
/* USER CODE END FunctionPrototypes */
/* Hook prototypes */
void vApplicationIdleHook(void);
void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTaskName);
@@ -135,8 +153,11 @@ void init_deferred_interrupts(void) {
/* USER CODE END 4 */
/* Init FreeRTOS */
/**
* @brief FreeRTOS initialization
* @param None
* @retval None
*/
void MX_FREERTOS_Init(void) {
/* USER CODE BEGIN Init */
@@ -186,7 +207,13 @@ void MX_FREERTOS_Init(void) {
/* USER CODE END RTOS_QUEUES */
}
/* StartDefaultTask function */
/* USER CODE BEGIN Header_StartDefaultTask */
/**
* @brief Function implementing the defaultTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void * argument)
{
/* init code for USB_DEVICE */
@@ -202,6 +229,7 @@ void StartDefaultTask(void * argument)
/* USER CODE END StartDefaultTask */
}
/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
/* USER CODE END Application */
+3 -1
View File
@@ -1,3 +1,4 @@
/**
******************************************************************************
* @file : main.c
@@ -179,7 +180,7 @@ int main(void)
MX_DMA_Init();
MX_ADC1_Init();
MX_ADC2_Init();
MX_CAN1_Init();
// MX_CAN1_Init(); // CAN or I2C called in main.cpp instead
MX_TIM1_Init();
MX_TIM8_Init();
MX_TIM3_Init();
@@ -189,6 +190,7 @@ int main(void)
MX_TIM2_Init();
MX_UART4_Init();
MX_TIM5_Init();
MX_TIM13_Init();
/* USER CODE BEGIN 2 */
//Required to use OC4 for ADC triggering.
+49
View File
@@ -51,12 +51,15 @@
#include "spi.h"
#include "gpio.h"
#include "dma.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
SPI_HandleTypeDef hspi3;
DMA_HandleTypeDef hdma_spi3_tx;
DMA_HandleTypeDef hdma_spi3_rx;
/* SPI3 init function */
void MX_SPI3_Init(void)
@@ -105,6 +108,46 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* SPI3 DMA Init */
/* SPI3_TX Init */
hdma_spi3_tx.Instance = DMA1_Stream5;
hdma_spi3_tx.Init.Channel = DMA_CHANNEL_0;
hdma_spi3_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi3_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi3_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi3_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_spi3_tx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_spi3_tx.Init.Mode = DMA_NORMAL;
hdma_spi3_tx.Init.Priority = DMA_PRIORITY_MEDIUM;
hdma_spi3_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_spi3_tx) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(spiHandle,hdmatx,hdma_spi3_tx);
/* SPI3_RX Init */
hdma_spi3_rx.Instance = DMA1_Stream0;
hdma_spi3_rx.Init.Channel = DMA_CHANNEL_0;
hdma_spi3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_spi3_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi3_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_spi3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_spi3_rx.Init.Mode = DMA_NORMAL;
hdma_spi3_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
hdma_spi3_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_spi3_rx) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(spiHandle,hdmarx,hdma_spi3_rx);
/* SPI3 interrupt Init */
HAL_NVIC_SetPriority(SPI3_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(SPI3_IRQn);
/* USER CODE BEGIN SPI3_MspInit 1 */
/* USER CODE END SPI3_MspInit 1 */
@@ -129,6 +172,12 @@ void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle)
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12);
/* SPI3 DMA DeInit */
HAL_DMA_DeInit(spiHandle->hdmatx);
HAL_DMA_DeInit(spiHandle->hdmarx);
/* SPI3 interrupt Deinit */
HAL_NVIC_DisableIRQ(SPI3_IRQn);
/* USER CODE BEGIN SPI3_MspDeInit 1 */
/* USER CODE END SPI3_MspDeInit 1 */
+3 -1
View File
@@ -48,7 +48,6 @@
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
extern void _Error_Handler(char *, int);
/* USER CODE BEGIN 0 */
@@ -62,6 +61,9 @@ void HAL_MspInit(void)
/* USER CODE END MspInit 0 */
__HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_RCC_PWR_CLK_ENABLE();
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
/* System interrupt init*/
+45
View File
@@ -63,6 +63,9 @@ extern ADC_HandleTypeDef hadc1;
extern ADC_HandleTypeDef hadc2;
extern ADC_HandleTypeDef hadc3;
extern CAN_HandleTypeDef hcan1;
extern DMA_HandleTypeDef hdma_spi3_tx;
extern DMA_HandleTypeDef hdma_spi3_rx;
extern SPI_HandleTypeDef hspi3;
extern TIM_HandleTypeDef htim5;
extern TIM_HandleTypeDef htim8;
extern DMA_HandleTypeDef hdma_uart4_rx;
@@ -194,6 +197,20 @@ void SysTick_Handler(void)
/* please refer to the startup file (startup_stm32f4xx.s). */
/******************************************************************************/
/**
* @brief This function handles DMA1 stream0 global interrupt.
*/
void DMA1_Stream0_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Stream0_IRQn 0 */
/* USER CODE END DMA1_Stream0_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_spi3_rx);
/* USER CODE BEGIN DMA1_Stream0_IRQn 1 */
/* USER CODE END DMA1_Stream0_IRQn 1 */
}
/**
* @brief This function handles DMA1 stream2 global interrupt.
*/
@@ -222,6 +239,20 @@ void DMA1_Stream4_IRQHandler(void)
/* USER CODE END DMA1_Stream4_IRQn 1 */
}
/**
* @brief This function handles DMA1 stream5 global interrupt.
*/
void DMA1_Stream5_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Stream5_IRQn 0 */
/* USER CODE END DMA1_Stream5_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_spi3_tx);
/* USER CODE BEGIN DMA1_Stream5_IRQn 1 */
/* USER CODE END DMA1_Stream5_IRQn 1 */
}
/**
* @brief This function handles ADC1, ADC2 and ADC3 global interrupts.
*/
@@ -336,6 +367,20 @@ void TIM5_IRQHandler(void)
/* USER CODE END TIM5_IRQn 1 */
}
/**
* @brief This function handles SPI3 global interrupt.
*/
void SPI3_IRQHandler(void)
{
/* USER CODE BEGIN SPI3_IRQn 0 */
/* USER CODE END SPI3_IRQn 0 */
HAL_SPI_IRQHandler(&hspi3);
/* USER CODE BEGIN SPI3_IRQn 1 */
/* USER CODE END SPI3_IRQn 1 */
}
/**
* @brief This function handles UART4 global interrupt.
*/
+62 -3
View File
@@ -80,6 +80,7 @@ TIM_HandleTypeDef htim3;
TIM_HandleTypeDef htim4;
TIM_HandleTypeDef htim5;
TIM_HandleTypeDef htim8;
TIM_HandleTypeDef htim13;
/* TIM1 init function */
void MX_TIM1_Init(void)
@@ -94,7 +95,7 @@ void MX_TIM1_Init(void)
htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED3;
htim1.Init.Period = TIM_1_8_PERIOD_CLOCKS;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.RepetitionCounter = TIM_1_8_RCR;
if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
@@ -324,7 +325,7 @@ void MX_TIM8_Init(void)
htim8.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED3;
htim8.Init.Period = TIM_1_8_PERIOD_CLOCKS;
htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim8.Init.RepetitionCounter = 0;
htim8.Init.RepetitionCounter = TIM_1_8_RCR;
if (HAL_TIM_PWM_Init(&htim8) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
@@ -373,6 +374,21 @@ void MX_TIM8_Init(void)
HAL_TIM_MspPostInit(&htim8);
}
/* TIM13 init function */
void MX_TIM13_Init(void)
{
htim13.Instance = TIM13;
htim13.Init.Prescaler = 0;
htim13.Init.CounterMode = TIM_COUNTERMODE_UP;
htim13.Init.Period = (2 * TIM_1_8_PERIOD_CLOCKS * (TIM_1_8_RCR+1)) * ((float)TIM_APB1_CLOCK_HZ / (float)TIM_1_8_CLOCK_HZ) - 1;
htim13.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
if (HAL_TIM_Base_Init(&htim13) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
@@ -393,6 +409,21 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
/* USER CODE END TIM1_MspInit 1 */
}
else if(tim_baseHandle->Instance==TIM13)
{
/* USER CODE BEGIN TIM13_MspInit 0 */
/* USER CODE END TIM13_MspInit 0 */
/* TIM13 clock enable */
__HAL_RCC_TIM13_CLK_ENABLE();
/* TIM13 interrupt Init */
HAL_NVIC_SetPriority(TIM8_UP_TIM13_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM8_UP_TIM13_IRQn);
/* USER CODE BEGIN TIM13_MspInit 1 */
/* USER CODE END TIM13_MspInit 1 */
}
}
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* tim_pwmHandle)
@@ -626,6 +657,27 @@ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
/* USER CODE END TIM1_MspDeInit 1 */
}
else if(tim_baseHandle->Instance==TIM13)
{
/* USER CODE BEGIN TIM13_MspDeInit 0 */
/* USER CODE END TIM13_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM13_CLK_DISABLE();
/* TIM13 interrupt Deinit */
/* USER CODE BEGIN TIM13:TIM8_UP_TIM13_IRQn disable */
/**
* Uncomment the line below to disable the "TIM8_UP_TIM13_IRQn" interrupt
* Be aware, disabling shared interrupt may affect other IPs
*/
/* HAL_NVIC_DisableIRQ(TIM8_UP_TIM13_IRQn); */
/* USER CODE END TIM13:TIM8_UP_TIM13_IRQn disable */
/* USER CODE BEGIN TIM13_MspDeInit 1 */
/* USER CODE END TIM13_MspDeInit 1 */
}
}
void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef* tim_pwmHandle)
@@ -651,7 +703,14 @@ void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef* tim_pwmHandle)
__HAL_RCC_TIM8_CLK_DISABLE();
/* TIM8 interrupt Deinit */
HAL_NVIC_DisableIRQ(TIM8_UP_TIM13_IRQn);
/* USER CODE BEGIN TIM8:TIM8_UP_TIM13_IRQn disable */
/**
* Uncomment the line below to disable the "TIM8_UP_TIM13_IRQn" interrupt
* Be aware, disabling shared interrupt may affect other IPs
*/
/* HAL_NVIC_DisableIRQ(TIM8_UP_TIM13_IRQn); */
/* USER CODE END TIM8:TIM8_UP_TIM13_IRQn disable */
HAL_NVIC_DisableIRQ(TIM8_TRG_COM_TIM14_IRQn);
/* USER CODE BEGIN TIM8_MspDeInit 1 */
+1 -1
View File
@@ -66,7 +66,7 @@ void MX_UART4_Init(void)
{
huart4.Instance = UART4;
huart4.Init.BaudRate = 115200;
huart4.Init.BaudRate = 115200; // Provisionally this can be changed to 921600 for faster transfers, the low power Arduinos will not keep up.
huart4.Init.WordLength = UART_WORDLENGTH_8B;
huart4.Init.StopBits = UART_STOPBITS_1;
huart4.Init.Parity = UART_PARITY_NONE;
+30 -17
View File
@@ -30,6 +30,7 @@ Axis::Axis(const AxisHardwareConfig_t& hw_config,
controller_.axis_ = this;
motor_.axis_ = this;
trap_.axis_ = this;
decode_step_dir_pins();
min_endstop_.axis_ = this;
max_endstop_.axis_ = this;
}
@@ -73,33 +74,46 @@ bool Axis::wait_for_current_meas() {
// step/direction interface
void Axis::step_cb() {
if (enable_step_dir_) {
GPIO_PinState dir_pin = HAL_GPIO_ReadPin(hw_config_.dir_port, hw_config_.dir_pin);
if (step_dir_active_) {
GPIO_PinState dir_pin = HAL_GPIO_ReadPin(dir_port_, dir_pin_);
float dir = (dir_pin == GPIO_PIN_SET) ? 1.0f : -1.0f;
controller_.pos_setpoint_ += dir * config_.counts_per_step;
}
};
// @brief Enables or disables step/dir input
void Axis::set_step_dir_enabled(bool enable) {
if (enable) {
void Axis::load_default_step_dir_pin_config(
const AxisHardwareConfig_t& hw_config, Config_t* config) {
config->step_gpio_pin = hw_config.step_gpio_pin;
config->dir_gpio_pin = hw_config.dir_gpio_pin;
}
void Axis::decode_step_dir_pins() {
step_port_ = get_gpio_port_by_pin(config_.step_gpio_pin);
step_pin_ = get_gpio_pin_by_pin(config_.step_gpio_pin);
dir_port_ = get_gpio_port_by_pin(config_.dir_gpio_pin);
dir_pin_ = get_gpio_pin_by_pin(config_.dir_gpio_pin);
}
// @brief (de)activates step/dir input
void Axis::set_step_dir_active(bool active) {
if (active) {
// Set up the direction GPIO as input
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = hw_config_.dir_pin;
GPIO_InitStruct.Pin = dir_pin_;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(hw_config_.dir_port, &GPIO_InitStruct);
HAL_GPIO_Init(dir_port_, &GPIO_InitStruct);
// Subscribe to rising edges of the step GPIO
GPIO_subscribe(hw_config_.step_port, hw_config_.step_pin, GPIO_PULLDOWN,
GPIO_subscribe(step_port_, step_pin_, GPIO_PULLDOWN,
GPIO_MODE_IT_FALLING, step_cb_wrapper, this);
enable_step_dir_ = true;
step_dir_active_ = true;
} else {
enable_step_dir_ = false;
step_dir_active_ = false;
// Unsubscribe from step GPIO
GPIO_unsubscribe(hw_config_.step_port, hw_config_.step_pin);
GPIO_unsubscribe(step_port_, step_pin_);
}
}
@@ -176,8 +190,6 @@ bool Axis::run_sensorless_spin_up() {
// Note run_sensorless_control_loop and run_closed_loop_control_loop are very similar and differ only in where we get the estimate from.
bool Axis::run_sensorless_control_loop() {
set_step_dir_enabled(config_.enable_step_dir);
run_control_loop([this](){
if (controller_.config_.control_mode >= Controller::CTRL_MODE_POSITION_CONTROL)
return error_ |= ERROR_POS_CTRL_DURING_SENSORLESS, false;
@@ -190,13 +202,14 @@ bool Axis::run_sensorless_control_loop() {
return false; // set_error should update axis.error_
return true;
});
set_step_dir_enabled(false);
return check_for_errors();
}
bool Axis::run_closed_loop_control_loop() {
set_step_dir_enabled(config_.enable_step_dir);
run_control_loop([this]() {
// To avoid any transient on startup, we intialize the setpoint to be the current position
controller_.pos_setpoint_ = encoder_.pos_estimate_;
set_step_dir_active(config_.enable_step_dir);
run_control_loop([this](){
// Note that all estimators are updated in the loop prefix in run_control_loop
float current_setpoint;
if (!controller_.update(encoder_.pos_estimate_, encoder_.vel_estimate_, &current_setpoint))
@@ -225,7 +238,7 @@ bool Axis::run_closed_loop_control_loop() {
}
return true;
});
set_step_dir_enabled(false);
set_step_dir_active(false);
return check_for_errors();
}
+23 -7
View File
@@ -22,9 +22,9 @@ public:
ERROR_CURRENT_MEASUREMENT_TIMEOUT = 0x08,
ERROR_BRAKE_RESISTOR_DISARMED = 0x10, //<! the brake resistor was unexpectedly disarmed
ERROR_MOTOR_DISARMED = 0x20, //<! the motor was unexpectedly disarmed
ERROR_MOTOR_FAILED = 0x40,
ERROR_MOTOR_FAILED = 0x40, // Go to motor.hpp for information, check odrvX.axisX.motor.error for error value
ERROR_SENSORLESS_ESTIMATOR_FAILED = 0x80,
ERROR_ENCODER_FAILED = 0x100,
ERROR_ENCODER_FAILED = 0x100, // Go to encoder.hpp for information, check odrvX.axisX.encoder.error for error value
ERROR_CONTROLLER_FAILED = 0x200,
ERROR_POS_CTRL_DURING_SENSORLESS = 0x400,
ERROR_MIN_ENDSTOP_PRESSED = 0x800,
@@ -56,9 +56,12 @@ public:
bool startup_homing = false; //<! enable homing after calibration/startup
bool enable_step_dir = false; //<! enable step/dir input after calibration
// For M0 this has no effect if enable_uart is true
float counts_per_step = 2.0f;
// Defaults loaded from hw_config in load_configuration in main.cpp
uint16_t step_gpio_pin = 0;
uint16_t dir_gpio_pin = 0;
// Spinup settings
float ramp_up_time = 0.4f; // [s]
float ramp_up_distance = 4 * M_PI; // [rad]
@@ -87,8 +90,10 @@ public:
bool wait_for_current_meas();
void step_cb();
void set_step_dir_enabled(bool enable);
void set_step_dir_active(bool enable);
void decode_step_dir_pins();
static void load_default_step_dir_pin_config(
const AxisHardwareConfig_t& hw_config, Config_t* config);
bool check_DRV_fault();
bool check_PSU_brownout();
@@ -183,7 +188,14 @@ public:
// variables exposed on protocol
Error_t error_ = ERROR_NONE;
bool enable_step_dir_ = false; // auto enabled after calibration, based on config.enable_step_dir
bool step_dir_active_ = false; // auto enabled after calibration, based on config.enable_step_dir
// updated from config in constructor, and on protocol hook
GPIO_TypeDef* step_port_;
uint16_t step_pin_;
GPIO_TypeDef* dir_port_;
uint16_t dir_pin_;
State_t requested_state_ = AXIS_STATE_STARTUP_SEQUENCE;
State_t task_chain_[10] = { AXIS_STATE_UNDEFINED };
State_t& current_state_ = task_chain_[0];
@@ -194,7 +206,7 @@ public:
auto make_protocol_definitions() {
return make_protocol_member_list(
make_protocol_property("error", &error_),
make_protocol_property("enable_step_dir", &enable_step_dir_),
make_protocol_ro_property("step_dir_active", &step_dir_active_),
make_protocol_ro_property("current_state", &current_state_),
make_protocol_property("requested_state", &requested_state_),
make_protocol_ro_property("loop_counter", &loop_counter_),
@@ -208,6 +220,10 @@ public:
make_protocol_property("startup_homing", &config_.startup_homing),
make_protocol_property("enable_step_dir", &config_.enable_step_dir),
make_protocol_property("counts_per_step", &config_.counts_per_step),
make_protocol_property("step_gpio_pin", &config_.step_gpio_pin,
[](void* ctx) { static_cast<Axis*>(ctx)->decode_step_dir_pins(); }, this),
make_protocol_property("dir_gpio_pin", &config_.dir_gpio_pin,
[](void* ctx) { static_cast<Axis*>(ctx)->decode_step_dir_pins(); }, this),
make_protocol_property("ramp_up_time", &config_.ramp_up_time),
make_protocol_property("ramp_up_distance", &config_.ramp_up_distance),
make_protocol_property("spin_up_current", &config_.spin_up_current),
+9 -17
View File
@@ -21,10 +21,8 @@
typedef struct {
GPIO_TypeDef* step_port;
uint16_t step_pin;
GPIO_TypeDef* dir_port;
uint16_t dir_pin;
uint16_t step_gpio_pin;
uint16_t dir_gpio_pin;
size_t thermistor_adc_ch;
osPriority thread_priority;
} AxisHardwareConfig_t;
@@ -68,16 +66,14 @@ extern const size_t thermistor_num_coeffs;
//TODO stick this in a C file
#ifdef __MAIN_CPP__
const float thermistor_poly_coeffs[] =
{363.0172658f, -459.19773008f, 308.29273921f, -28.12731452f};
{363.93910201f, -462.15369634f, 307.55129571f, -27.72569531f};
const size_t thermistor_num_coeffs = sizeof(thermistor_poly_coeffs)/sizeof(thermistor_poly_coeffs[1]);
const BoardHardwareConfig_t hw_configs[2] = { {
//M0
.axis_config = {
.step_port = GPIO_1_GPIO_Port,
.step_pin = GPIO_1_Pin,
.dir_port = GPIO_2_GPIO_Port,
.dir_pin = GPIO_2_Pin,
.step_gpio_pin = 1,
.dir_gpio_pin = 2,
.thermistor_adc_ch = 15,
.thread_priority = (osPriority)(osPriorityHigh + (osPriority)1),
},
@@ -111,15 +107,11 @@ const BoardHardwareConfig_t hw_configs[2] = { {
//M1
.axis_config = {
#if HW_VERSION_MAJOR == 3 && HW_VERSION_MINOR >= 5
.step_port = GPIO_7_GPIO_Port,
.step_pin = GPIO_7_Pin,
.dir_port = GPIO_8_GPIO_Port,
.dir_pin = GPIO_8_Pin,
.step_gpio_pin = 7,
.dir_gpio_pin = 8,
#else
.step_port = GPIO_3_GPIO_Port,
.step_pin = GPIO_3_Pin,
.dir_port = GPIO_4_GPIO_Port,
.dir_pin = GPIO_4_Pin,
.step_gpio_pin = 3,
.dir_gpio_pin = 4,
#endif
#if HW_VERSION_MAJOR == 3 && HW_VERSION_MINOR >= 3
.thermistor_adc_ch = 4,
+39 -1
View File
@@ -13,6 +13,11 @@ void Controller::reset() {
current_setpoint_ = 0.0f;
}
void Controller::set_error(Error_t error) {
error_ |= error;
axis_->error_ |= Axis::ERROR_CONTROLLER_FAILED;
}
//--------------------------------
// Command Handling
//--------------------------------
@@ -125,11 +130,36 @@ bool Controller::update(float pos_estimate, float vel_estimate, float* current_s
anticogging_pos = pos_setpoint_; // FF the position setpoint instead of the pos_estimate
}
// Ramp rate limited velocity setpoint
if (config_.control_mode == CTRL_MODE_VELOCITY_CONTROL && vel_ramp_enable_) {
float max_step_size = current_meas_period * config_.vel_ramp_rate;
float full_step = vel_ramp_target_ - vel_setpoint_;
float step;
if (fabsf(full_step) > max_step_size) {
step = std::copysignf(max_step_size, full_step);
} else {
step = full_step;
}
vel_setpoint_ += step;
}
// Position control
// TODO Decide if we want to use encoder or pll position here
float vel_des = vel_setpoint_;
if (config_.control_mode >= CTRL_MODE_POSITION_CONTROL) {
float pos_err = pos_setpoint_ - pos_estimate;
float pos_err;
if (config_.setpoints_in_cpr) {
// TODO this breaks the semantics that estimates come in on the arguments.
// It's probably better to call a get_estimate that will arbitrate (enc vs sensorless) instead.
float cpr = (float)(axis_->encoder_.config_.cpr);
// Keep pos setpoint from drifting
pos_setpoint_ = fmodf_pos(pos_setpoint_, cpr);
// Circular delta
pos_err = pos_setpoint_ - axis_->encoder_.pos_cpr_;
pos_err = wrap_pm(pos_err, 0.5f * cpr);
} else {
pos_err = pos_setpoint_ - pos_estimate;
}
vel_des += config_.pos_gain * pos_err;
}
@@ -138,6 +168,14 @@ bool Controller::update(float pos_estimate, float vel_estimate, float* current_s
if (vel_des > vel_lim) vel_des = vel_lim;
if (vel_des < -vel_lim) vel_des = -vel_lim;
// Check for overspeed fault (done in this module (controller) for cohesion with vel_lim)
if (config_.vel_limit_tolerance > 0.0f) { // 0.0f to disable
if (fabsf(vel_estimate) > config_.vel_limit_tolerance * vel_lim) {
set_error(ERROR_OVERSPEED);
return false;
}
}
// Velocity control
float Iq = current_setpoint_;
+22 -2
View File
@@ -7,6 +7,11 @@
class Controller {
public:
enum Error_t {
ERROR_NONE = 0,
ERROR_OVERSPEED = 0x01,
};
// Note: these should be sorted from lowest level of control to
// highest level of control, to allow "<" style comparisons.
enum ControlMode_t{
@@ -23,12 +28,16 @@ public:
float vel_gain = 5.0f / 10000.0f; // [A/(counts/s)]
// float vel_gain = 5.0f / 200.0f, // [A/(rad/s)] <sensorless example>
float vel_integrator_gain = 10.0f / 10000.0f; // [A/(counts/s * s)]
float vel_limit = 20000.0f; // [counts/s]
float vel_limit = 20000.0f; // [counts/s]
float vel_limit_tolerance = 1.2f; // ratio to vel_lim. 0.0f to disable
float vel_ramp_rate = 10000.0f; // [(counts/s) / s]
bool setpoints_in_cpr = false;
float homing_speed = 2000.0f; // [counts/s]
};
};
Controller(Config_t& config);
void reset();
void set_error(Error_t error);
void set_pos_setpoint(float pos_setpoint, float vel_feed_forward, float current_feed_forward);
void set_vel_setpoint(float vel_setpoint, float current_feed_forward);
@@ -71,28 +80,37 @@ public:
.calib_vel_threshold = 1.0f,
};
Error_t error_ = ERROR_NONE;
// variables exposed on protocol
float pos_setpoint_ = 0.0f;
float vel_setpoint_ = 0.0f;
// float vel_setpoint = 800.0f; <sensorless example>
float vel_integrator_current_ = 0.0f; // [A]
float current_setpoint_ = 0.0f; // [A]
float vel_ramp_target_ = 0.0f;
bool vel_ramp_enable_ = false;
uint32_t traj_start_loop_count_ = 0;
// Communication protocol definitions
auto make_protocol_definitions() {
return make_protocol_member_list(
make_protocol_property("error", &error_),
make_protocol_property("pos_setpoint", &pos_setpoint_),
make_protocol_property("vel_setpoint", &vel_setpoint_),
make_protocol_property("vel_integrator_current", &vel_integrator_current_),
make_protocol_property("current_setpoint", &current_setpoint_),
make_protocol_property("vel_ramp_target", &vel_ramp_target_),
make_protocol_property("vel_ramp_enable", &vel_ramp_enable_),
make_protocol_object("config",
make_protocol_property("control_mode", &config_.control_mode),
make_protocol_property("pos_gain", &config_.pos_gain),
make_protocol_property("vel_gain", &config_.vel_gain),
make_protocol_property("vel_integrator_gain", &config_.vel_integrator_gain),
make_protocol_property("vel_limit", &config_.vel_limit),
make_protocol_property("vel_limit_tolerance", &config_.vel_limit_tolerance),
make_protocol_property("vel_ramp_rate", &config_.vel_ramp_rate),
make_protocol_property("setpoints_in_cpr", &config_.setpoints_in_cpr)
make_protocol_property("homing_speed", &config_.homing_speed)
),
make_protocol_function("set_pos_setpoint", *this, &Controller::set_pos_setpoint,
@@ -108,4 +126,6 @@ public:
}
};
DEFINE_ENUM_FLAG_OPERATORS(Controller::Error_t)
#endif // __CONTROLLER_HPP
+7 -8
View File
@@ -24,7 +24,7 @@ void Encoder::setup() {
GPIO_MODE_IT_RISING, enc_index_cb_wrapper, this);
}
void Encoder::set_error(Encoder::Error_t error) {
void Encoder::set_error(Error_t error) {
error_ |= error;
axis_->error_ |= Axis::ERROR_ENCODER_FAILED;
}
@@ -44,7 +44,8 @@ bool Encoder::do_checks(){
void Encoder::enc_index_cb() {
if (config_.use_index && !index_found_) {
set_circular_count(0, false);
set_linear_count(0); // Avoid position control transient after search
if (config_.zero_count_on_find_idx)
set_linear_count(0); // Avoid position control transient after search
if (config_.pre_calibrated) {
is_ready_ = true;
} else {
@@ -60,8 +61,7 @@ void Encoder::enc_index_cb() {
// Function that sets the current encoder count to a desired 32-bit value.
void Encoder::set_linear_count(int32_t count) {
// Disable interrupts to make a critical section to avoid race condition
uint32_t prim = __get_PRIMASK();
__disable_irq();
uint32_t prim = cpu_enter_critical();
// Update states
shadow_count_ = count;
@@ -69,15 +69,14 @@ void Encoder::set_linear_count(int32_t count) {
//Write hardware last
hw_config_.timer->Instance->CNT = count;
__set_PRIMASK(prim);
cpu_exit_critical(prim);
}
// Function that sets the CPR circular tracking encoder count to a desired 32-bit value.
// Note that this will get mod'ed down to [0, cpr)
void Encoder::set_circular_count(int32_t count, bool update_offset) {
// Disable interrupts to make a critical section to avoid race condition
uint32_t prim = __get_PRIMASK();
__disable_irq();
uint32_t prim = cpu_enter_critical();
if (update_offset) {
config_.offset += count - count_in_cpr_;
@@ -88,7 +87,7 @@ void Encoder::set_circular_count(int32_t count, bool update_offset) {
count_in_cpr_ = mod(count, config_.cpr);
pos_cpr_ = (float)count_in_cpr_;
__set_PRIMASK(prim);
cpu_exit_critical(prim);
}
+8 -6
View File
@@ -31,6 +31,7 @@ public:
// In this case the encoder will enter ready
// state as soon as the index is found.
float idx_search_speed = 10.0f; // [rad/s electrical]
bool zero_count_on_find_idx = true;
int32_t cpr = (2048 * 4); // Default resolution of CUI-AMT102 encoder,
int32_t offset = 0; // Offset between encoder count and rotor electrical phase
float offset_float = 0.0f; // Sub-count phase alignment offset
@@ -68,12 +69,12 @@ public:
int32_t shadow_count_ = 0;
int32_t count_in_cpr_ = 0;
float interpolation_ = 0.0f;
float phase_ = 0.0f; // [rad]
float pos_estimate_ = 0.0f; // [rad]
float pos_cpr_ = 0.0f; // [rad]
float vel_estimate_ = 0.0f; // [rad/s]
float pll_kp_ = 0.0f; // [rad/s / rad]
float pll_ki_ = 0.0f; // [(rad/s^2) / rad]
float phase_ = 0.0f; // [count]
float pos_estimate_ = 0.0f; // [count]
float pos_cpr_ = 0.0f; // [count]
float vel_estimate_ = 0.0f; // [count/s]
float pll_kp_ = 0.0f; // [count/s / count]
float pll_ki_ = 0.0f; // [(count/s^2) / count]
// Updated by low_level pwm_adc_cb
uint8_t hall_state_ = 0x0; // bit[0] = HallA, .., bit[2] = HallC
@@ -99,6 +100,7 @@ public:
make_protocol_property("use_index", &config_.use_index),
make_protocol_property("pre_calibrated", &config_.pre_calibrated),
make_protocol_property("idx_search_speed", &config_.idx_search_speed),
make_protocol_property("zero_count_on_find_idx", &config_.zero_count_on_find_idx),
make_protocol_property("cpr", &config_.cpr),
make_protocol_property("offset", &config_.offset),
make_protocol_property("offset_float", &config_.offset_float),
+29 -40
View File
@@ -45,25 +45,6 @@ static const int num_GPIO = sizeof(GPIOs_to_samp) / sizeof(GPIOs_to_samp[0]);
static uint16_t GPIO_port_samples [2][num_GPIO];
/* CPU critical section helpers ----------------------------------------------*/
static inline uint8_t cpu_enter_critical() {
uint8_t status_register;
asm (
"MRS R0, PRIMASK\n\t"
"CPSID I\n\t"
"STRB R0, %[output]"
: [output] "=m" (status_register) :: "r0"
);
return status_register;
}
static inline void cpu_exit_critical(uint8_t status_register) {
asm (
"ldrb r0, %[input]\n\t"
"msr PRIMASK,r0;\n\t"
::[input] "m" (status_register) : "r0"
);
}
/* Safety critical functions -------------------------------------------------*/
/*
@@ -115,11 +96,11 @@ void low_level_fault(Motor::Error_t error) {
// All calls to this function must clearly originate
// from user input.
void safety_critical_arm_motor_pwm(Motor& motor) {
uint8_t sr = cpu_enter_critical();
uint32_t mask = cpu_enter_critical();
if (brake_resistor_armed) {
motor.armed_state_ = Motor::ARMED_STATE_WAITING_FOR_TIMINGS;
}
cpu_exit_critical(sr);
cpu_exit_critical(mask);
}
// @brief Disarms the motor PWM.
@@ -128,11 +109,11 @@ void safety_critical_arm_motor_pwm(Motor& motor) {
// safety_critical_arm_motor_phases is called.
// @returns true if the motor was in a state other than disarmed before
bool safety_critical_disarm_motor_pwm(Motor& motor) {
uint8_t sr = cpu_enter_critical();
uint32_t mask = cpu_enter_critical();
bool was_armed = motor.armed_state_ != Motor::ARMED_STATE_DISARMED;
motor.armed_state_ = Motor::ARMED_STATE_DISARMED;
__HAL_TIM_MOE_DISABLE_UNCONDITIONALLY(motor.hw_config_.timer);
cpu_exit_critical(sr);
cpu_exit_critical(mask);
return was_armed;
}
@@ -142,7 +123,7 @@ bool safety_critical_disarm_motor_pwm(Motor& motor) {
// the actual PMW timings on the pins can be undefined for up to one
// timer period.
void safety_critical_apply_motor_pwm_timings(Motor& motor, uint16_t timings[3]) {
uint8_t sr = cpu_enter_critical();
uint32_t mask = cpu_enter_critical();
if (!brake_resistor_armed) {
motor.armed_state_ = Motor::ARMED_STATE_ARMED;
}
@@ -168,16 +149,16 @@ void safety_critical_apply_motor_pwm_timings(Motor& motor, uint16_t timings[3])
// unknown state oh no
safety_critical_disarm_motor_pwm(motor);
}
cpu_exit_critical(sr);
cpu_exit_critical(mask);
}
// @brief Arms the brake resistor
void safety_critical_arm_brake_resistor() {
uint8_t sr = cpu_enter_critical();
uint32_t mask = cpu_enter_critical();
brake_resistor_armed = true;
htim2.Instance->CCR3 = 0;
htim2.Instance->CCR4 = TIM_APB1_PERIOD_CLOCKS + 1;
cpu_exit_critical(sr);
cpu_exit_critical(mask);
}
// @brief Disarms the brake resistor and by extension
@@ -185,14 +166,14 @@ void safety_critical_arm_brake_resistor() {
// After calling this, the brake resistor can only be armed again
// by calling safety_critical_arm_brake_resistor().
void safety_critical_disarm_brake_resistor() {
uint8_t sr = cpu_enter_critical();
uint32_t mask = cpu_enter_critical();
brake_resistor_armed = false;
htim2.Instance->CCR3 = 0;
htim2.Instance->CCR4 = TIM_APB1_PERIOD_CLOCKS + 1;
for (size_t i = 0; i < AXIS_COUNT; ++i) {
safety_critical_disarm_motor_pwm(axes[i]->motor_);
}
cpu_exit_critical(sr);
cpu_exit_critical(mask);
}
// @brief Updates the brake resistor PWM timings unless
@@ -200,7 +181,7 @@ void safety_critical_disarm_brake_resistor() {
void safety_critical_apply_brake_resistor_timings(uint32_t low_off, uint32_t high_on) {
if (high_on - low_off < TIM_APB1_DEADTIME_CLOCKS)
low_level_fault(Motor::ERROR_BRAKE_DEADTIME_VIOLATION);
uint8_t sr = cpu_enter_critical();
uint32_t mask = cpu_enter_critical();
if (brake_resistor_armed) {
// Safe update of low and high side timings
// To avoid race condition, first reset timings to safe state
@@ -210,7 +191,7 @@ void safety_critical_apply_brake_resistor_timings(uint32_t low_off, uint32_t hig
htim2.Instance->CCR3 = low_off;
htim2.Instance->CCR4 = high_on;
}
cpu_exit_critical(sr);
cpu_exit_critical(mask);
}
/* Function implementations --------------------------------------------------*/
@@ -235,7 +216,8 @@ void start_adc_pwm() {
start_pwm(&htim1);
start_pwm(&htim8);
// TODO: explain why this offset
sync_timers(&htim1, &htim8, TIM_CLOCKSOURCE_ITR0, TIM_1_8_PERIOD_CLOCKS / 2 - 1 * 128);
sync_timers(&htim1, &htim8, TIM_CLOCKSOURCE_ITR0, TIM_1_8_PERIOD_CLOCKS / 2 - 1 * 128,
&htim13);
// Motor output starts in the disabled state
__HAL_TIM_MOE_DISABLE_UNCONDITIONALLY(&htim1);
@@ -278,7 +260,8 @@ void start_pwm(TIM_HandleTypeDef* htim) {
}
void sync_timers(TIM_HandleTypeDef* htim_a, TIM_HandleTypeDef* htim_b,
uint16_t TIM_CLOCKSOURCE_ITRx, uint16_t count_offset) {
uint16_t TIM_CLOCKSOURCE_ITRx, uint16_t count_offset,
TIM_HandleTypeDef* htim_refbase) {
// Store intial timer configs
uint16_t MOE_store_a = htim_a->Instance->BDTR & (TIM_BDTR_MOE);
uint16_t MOE_store_b = htim_b->Instance->BDTR & (TIM_BDTR_MOE);
@@ -313,6 +296,11 @@ void sync_timers(TIM_HandleTypeDef* htim_a, TIM_HandleTypeDef* htim_b,
// set counter offset
htim_a->Instance->CNT = count_offset;
htim_b->Instance->CNT = 0;
// Set and start reference timebase timer (if used)
if (htim_refbase) {
htim_refbase->Instance->CNT = count_offset;
htim_refbase->Instance->CR1 |= (TIM_CR1_CEN); // start
}
// Start Timer a
htim_a->Instance->CR1 |= (TIM_CR1_CEN);
// Restore timer configs
@@ -494,8 +482,14 @@ void pwm_trig_adc_cb(ADC_HandleTypeDef* hadc, bool injected) {
int axis_num = injected ? 0 : 1;
Axis& other_axis = injected ? *axes[1] : *axes[0];
bool counting_down = axis.motor_.hw_config_.timer->Instance->CR1 & TIM_CR1_DIR;
bool current_meas_not_DC_CAL = !counting_down;
// Check the timing of the sequencing
if (current_meas_not_DC_CAL)
axis.motor_.log_timing(Motor::TIMING_LOG_ADC_CB_I);
else
axis.motor_.log_timing(Motor::TIMING_LOG_ADC_CB_DC);
bool update_timings = false;
if (hadc == &hadc2) {
if (&axis == axes[1] && counting_down)
@@ -522,12 +516,6 @@ void pwm_trig_adc_cb(ADC_HandleTypeDef* hadc, bool injected) {
update_brake_current();
}
// Check the timing of the sequencing
if (current_meas_not_DC_CAL)
axis.motor_.log_timing(Motor::TIMING_LOG_ADC_CB_I);
else
axis.motor_.log_timing(Motor::TIMING_LOG_ADC_CB_DC);
uint32_t ADCValue;
if (injected) {
ADCValue = HAL_ADCEx_InjectedGetValue(hadc, ADC_INJECTED_RANK_1);
@@ -679,6 +667,7 @@ void pwm_in_init() {
}
}
//TODO: These expressions have integer division by 1MHz, so it will be incorrect for clock speeds of not-integer MHz
#define TIM_2_5_CLOCK_HZ TIM_APB1_CLOCK_HZ
#define PWM_MIN_HIGH_TIME ((TIM_2_5_CLOCK_HZ / 1000000UL) * 1000UL) // 1ms high is considered full reverse
#define PWM_MAX_HIGH_TIME ((TIM_2_5_CLOCK_HZ / 1000000UL) * 2000UL) // 2ms high is considered full forward
+12 -1
View File
@@ -46,13 +46,24 @@ void pwm_in_cb(int channel, uint32_t timestamp);
void start_adc_pwm();
void start_pwm(TIM_HandleTypeDef* htim);
void sync_timers(TIM_HandleTypeDef* htim_a, TIM_HandleTypeDef* htim_b,
uint16_t TIM_CLOCKSOURCE_ITRx, uint16_t count_offset);
uint16_t TIM_CLOCKSOURCE_ITRx, uint16_t count_offset,
TIM_HandleTypeDef* htim_refbase = nullptr);
void start_general_purpose_adc();
float get_adc_voltage(GPIO_TypeDef* GPIO_port, uint16_t GPIO_pin);
void pwm_in_init();
void update_brake_current();
inline uint32_t cpu_enter_critical() {
uint32_t primask = __get_PRIMASK();
__disable_irq();
return primask;
}
inline void cpu_exit_critical(uint32_t priority_mask) {
__set_PRIMASK(priority_mask);
}
#ifdef __cplusplus
}
#endif
+2 -2
View File
@@ -73,6 +73,8 @@ void load_configuration(void) {
motor_configs[i] = Motor::Config_t();
trap_configs[i] = TrapezoidalTrajectory::Config_t();
axis_configs[i] = Axis::Config_t();
// Default step/dir pins are different, so we need to explicitly load them
Axis::load_default_step_dir_pin_config(hw_configs[i].axis_config, &axis_configs[i]);
min_endstop_configs[i] = Endstop::Config_t();
max_endstop_configs[i] = Endstop::Config_t();
}
@@ -190,8 +192,6 @@ int odrive_main(void) {
// TODO: make dynamically reconfigurable
#if HW_VERSION_MAJOR == 3 && HW_VERSION_MINOR >= 3
if (board_config.enable_uart) {
axes[0]->config_.enable_step_dir = false;
axes[0]->set_step_dir_enabled(false);
SetGPIO12toUART();
}
#endif
+14 -8
View File
@@ -73,7 +73,8 @@ void Motor::DRV8301_setup() {
// Solve for exact gain, then snap down to have equal or larger range as requested
// or largest possible range otherwise
static const float kMargin = 0.90f;
static const float max_output_swing = 1.6f; // [V] out of amplifier
static const float kTripMargin = 1.0f; // Trip level is at edge of linear range of amplifer
static const float max_output_swing = 1.35f; // [V] out of amplifier
float max_unity_gain_current = kMargin * max_output_swing * hw_config_.shunt_conductance; // [A]
float requested_gain = max_unity_gain_current / config_.requested_current_range; // [V/V]
@@ -99,6 +100,8 @@ void Motor::DRV8301_setup() {
phase_current_rev_gain_ = 1.0f / gain_snap_down->first;
// Clip all current control to actual usable range
current_control_.max_allowed_current = max_unity_gain_current * phase_current_rev_gain_;
// Set trip level
current_control_.overcurrent_trip_level = (kTripMargin / kMargin) * current_control_.max_allowed_current;
// We now have the gain settings we want to use, lets set up DRV chip
DRV_SPI_8301_Vars_t* local_regs = &gate_driver_regs_;
@@ -136,6 +139,8 @@ bool Motor::check_DRV_fault() {
void Motor::set_error(Motor::Error_t error){
error_ |= error;
axis_->error_ |= Axis::ERROR_MOTOR_FAILED;
safety_critical_disarm_motor_pwm(*this);
update_brake_current();
}
bool Motor::do_checks() {
@@ -147,13 +152,8 @@ bool Motor::do_checks() {
}
void Motor::log_timing(TimingLog_t log_idx) {
TIM_HandleTypeDef* htim = hw_config_.timer;
uint16_t timing = htim->Instance->CNT;
bool down = htim->Instance->CR1 & TIM_CR1_DIR;
if (down) {
uint16_t delta = TIM_1_8_PERIOD_CLOCKS - timing;
timing = TIM_1_8_PERIOD_CLOCKS + delta;
}
static const uint16_t clocks_per_cnt = (uint16_t)((float)TIM_1_8_CLOCK_HZ / (float)TIM_APB1_CLOCK_HZ);
uint16_t timing = clocks_per_cnt * htim13.Instance->CNT; // TODO: Use a hw_config
if (log_idx < TIMING_LOG_NUM_SLOTS) {
timing_log_[log_idx] = timing;
@@ -299,6 +299,12 @@ bool Motor::FOC_current(float Id_des, float Iq_des, float phase) {
// For Reporting
ictrl.Iq_setpoint = Iq_des;
// Check for current sense saturation
if (fabsf(current_meas_.phB) > ictrl.overcurrent_trip_level
|| fabsf(current_meas_.phC) > ictrl.overcurrent_trip_level) {
set_error(ERROR_CURRENT_SENSE_SATURATION);
}
// Clarke transform
float Ialpha = -current_meas_.phB - current_meas_.phC;
float Ibeta = one_by_sqrt3 * (current_meas_.phB - current_meas_.phC);
+10 -6
View File
@@ -20,7 +20,8 @@ public:
ERROR_BRAKE_CURRENT_OUT_OF_RANGE = 0x0040,
ERROR_MODULATION_MAGNITUDE = 0x0080,
ERROR_BRAKE_DEADTIME_VIOLATION = 0x0100,
ERROR_UNEXPECTED_TIMER_CALLBACK = 0x0200
ERROR_UNEXPECTED_TIMER_CALLBACK = 0x0200,
ERROR_CURRENT_SENSE_SATURATION = 0x0400
};
enum MotorType_t {
@@ -43,9 +44,10 @@ public:
// Voltage applied at end of cycle:
float final_v_alpha; // [V]
float final_v_beta; // [V]
float Iq_setpoint;
float Iq_measured;
float max_allowed_current;
float Iq_setpoint; // [A]
float Iq_measured; // [A]
float max_allowed_current; // [A]
float overcurrent_trip_level; // [A]
};
// NOTE: for gimbal motors, all units of A are instead V.
@@ -64,7 +66,7 @@ public:
// float current_lim = 70.0f; //[A]
float current_lim = 10.0f; //[A]
// Value used to compute shunt amplifier gains
float requested_current_range = 70.0f; // [A]
float requested_current_range = 60.0f; // [A]
float current_control_bandwidth = 1000.0f; // [rad/s]
};
@@ -153,6 +155,7 @@ public:
.Iq_setpoint = 0.0f,
.Iq_measured = 0.0f,
.max_allowed_current = 0.0f,
.overcurrent_trip_level = 0.0f,
};
DRV8301_FaultType_e drv_fault_ = DRV8301_FaultType_NoFault;
DRV_SPI_8301_Vars_t gate_driver_regs_; //Local view of DRV registers (initialized by DRV8301_setup)
@@ -178,7 +181,8 @@ public:
make_protocol_property("final_v_beta", &current_control_.final_v_beta),
make_protocol_property("Iq_setpoint", &current_control_.Iq_setpoint),
make_protocol_property("Iq_measured", &current_control_.Iq_measured),
make_protocol_property("max_allowed_current", &current_control_.max_allowed_current)
make_protocol_ro_property("max_allowed_current", &current_control_.max_allowed_current),
make_protocol_ro_property("overcurrent_trip_level", &current_control_.overcurrent_trip_level)
),
make_protocol_object("gate_driver",
make_protocol_ro_property("drv_fault", &drv_fault_)
+6 -13
View File
@@ -51,9 +51,8 @@ int SVM(float alpha, float beta, float* tA, float* tB, float* tC) {
*tA = (1.0f - t1 - t2) * 0.5f;
*tB = *tA + t1;
*tC = *tB + t2;
} break;
break;
}
// sextant v2-v3
case 2: {
// Vector on-times
@@ -64,9 +63,8 @@ int SVM(float alpha, float beta, float* tA, float* tB, float* tC) {
*tB = (1.0f - t2 - t3) * 0.5f;
*tA = *tB + t3;
*tC = *tA + t2;
} break;
break;
}
// sextant v3-v4
case 3: {
// Vector on-times
@@ -77,9 +75,8 @@ int SVM(float alpha, float beta, float* tA, float* tB, float* tC) {
*tB = (1.0f - t3 - t4) * 0.5f;
*tC = *tB + t3;
*tA = *tC + t4;
} break;
break;
}
// sextant v4-v5
case 4: {
// Vector on-times
@@ -90,9 +87,8 @@ int SVM(float alpha, float beta, float* tA, float* tB, float* tC) {
*tC = (1.0f - t4 - t5) * 0.5f;
*tB = *tC + t5;
*tA = *tB + t4;
} break;
break;
}
// sextant v5-v6
case 5: {
// Vector on-times
@@ -103,9 +99,8 @@ int SVM(float alpha, float beta, float* tA, float* tB, float* tC) {
*tC = (1.0f - t5 - t6) * 0.5f;
*tA = *tC + t5;
*tB = *tA + t6;
} break;
break;
}
// sextant v6-v1
case 6: {
// Vector on-times
@@ -116,9 +111,7 @@ int SVM(float alpha, float beta, float* tA, float* tB, float* tC) {
*tA = (1.0f - t6 - t1) * 0.5f;
*tC = *tA + t1;
*tB = *tC + t6;
break;
}
} break;
}
// if any of the results becomes NaN, result_valid will evaluate to false
+2
View File
@@ -99,6 +99,8 @@ function GCCToolchain(prefix, builddir, compiler_flags, linker_flags)
}
-- display the size
tup.frule{inputs={output_name..'.elf'}, command=prefix..'size %f'}
-- generate disassembly
tup.frule{inputs={output_name..'.elf'}, command=prefix..'objdump %f -dSC > %o', outputs={output_name..'.asm'}}
-- create *.hex and *.bin output formats
tup.frule{inputs={output_name..'.elf'}, command=prefix..'objcopy -O ihex %f %o', outputs={output_name..'.hex'}}
tup.frule{inputs={output_name..'.elf'}, command=prefix..'objcopy -O binary -S %f %o', outputs={output_name..'.bin'}}
+1 -1
View File
@@ -84,7 +84,7 @@ void init_communication(void) {
printf("hi!\r\n");
// Start command handling thread
osThreadDef(task_cmd_parse, communication_task, osPriorityNormal, 0, 5000 /* in 32-bit words */); // TODO: fix stack issues
osThreadDef(task_cmd_parse, communication_task, osPriorityNormal, 0, 6000 /* in 32-bit words */); // TODO: fix stack issues
comm_thread = osThreadCreate(osThread(task_cmd_parse), NULL);
while (!endpoint_list_valid)
+12 -6
View File
@@ -603,6 +603,14 @@ struct format_traits_t;
// static constexpr const char * fmt = "%f";
// static constexpr const char * fmtp = "%f";
// };
template<> struct format_traits_t<int64_t> { using type = void;
static constexpr const char * fmt = "%lld";
static constexpr const char * fmtp = "%lld";
};
template<> struct format_traits_t<uint64_t> { using type = void;
static constexpr const char * fmt = "%llu";
static constexpr const char * fmtp = "%llu";
};
template<> struct format_traits_t<int32_t> { using type = void;
static constexpr const char * fmt = "%ld";
static constexpr const char * fmtp = "%ld";
@@ -634,14 +642,12 @@ static bool to_string(const T& value, char * buffer, size_t length, int) {
return true;
}
// Special case for float because printf promotes float to double, and we get warnings
template<typename T>
template<typename T = float>
static bool to_string(const float& value, char * buffer, size_t length, int) {
snprintf(buffer, length, "%f", (double)value);
return true;
}
template<typename T>
template<typename T = bool>
static bool to_string(const bool& value, char * buffer, size_t length, int) {
buffer[0] = value ? '1' : '0';
buffer[1] = 0;
@@ -657,11 +663,11 @@ static bool from_string(const char * buffer, size_t length, T* property, int) {
return sscanf(buffer, format_traits_t<T>::fmt, property) == 1;
}
// Special case for float because printf promotes float to double, and we get warnings
template<typename T>
template<typename T = float>
static bool from_string(const char * buffer, size_t length, float* property, int) {
return sscanf(buffer, "%f", property) == 1;
}
template<typename T>
template<typename T = bool>
static bool from_string(const char * buffer, size_t length, bool* property, int) {
int val;
if (sscanf(buffer, "%d", &val) != 1)
+1
View File
@@ -81,6 +81,7 @@ def launch_shell(args,
# If IPython is installed, embed IPython shell, otherwise embed regular shell
if use_ipython:
help = lambda: print_help(args, len(discovered_devices) > 0) # Override help function # pylint: disable=W0612
locals()['__name__'] = globals()['__name__'] # to fix broken "%run -i script.py"
console = IPython.terminal.embed.InteractiveShellEmbed(banner1='')
console.runcode = console.run_code # hack to make IPython look like the regular console
interact = console
+124
View File
@@ -0,0 +1,124 @@
#!/usr/bin/python2
# run openocd (0.9.0) with :
# $ openocd -f stlink-v2-1.cfg -f stm32f4x.cfg &> /dev/null"
# then run
# $ python2 sampler.py path_to_myelf_with_symbols
import sys
import time
import telnetlib
import subprocess
from bisect import bisect_right
import operator
class OpenOCDCMSampler(object):
def __init__(self, host='localhost', port=4444):
self.net = telnetlib.Telnet(host, port)
self.net.read_very_eager()
self.table = []
self.indexes = set()
def __del__(self):
self.net.write(b'exit\r\n')
self.net.read_until(b'exit\r\n', 1)
self.net.close()
def getpc(self):
self.net.write(b'mrw 0xE000101C\r\n')
res = self.net.read_until(b'\r\n\r> ', 1)
if res:
prefix = res[0:16]
num = res[16:-5]
res = res[-15:0]
if prefix == b'mrw 0xE000101C\r\n':
return int(num)
return 0
def initSymbols(self, elf, readelf='arm-none-eabi-readelf'):
proc = subprocess.Popen([readelf, '-s', elf], stdout=subprocess.PIPE)
for line in proc.stdout.readlines():
field = line.split()
# for i,txt in enumerate(field):
# print("{}, {}".format(i, txt))
try:
if field[3] == b'FUNC':
addr = int(field[1], 16) - 1 # For some reason readelf dumps the func addr off by 1
func = field[7]
size = int(field[2])
if addr not in self.indexes:
self.table.append((addr, func, size))
self.indexes.add(addr)
except IndexError:
pass
self.table.sort()
self.addrs = [ x for (x, y, z) in self.table ]
def func(self, pc):
if pc == 0 or pc == 0xFFFFFFFF:
return ('', 0)
i = bisect_right(self.addrs, pc)
if i:
addr, symb, size = self.table[i-1]
if pc >= addr and pc <= addr + size:
return (symb, addr)
return ('', 0)
if __name__ == '__main__':
sampler = OpenOCDCMSampler('localhost', 4444)
sampler.initSymbols(sys.argv[1])
total = 0
countmap = { }
pcmap = { }
start = time.time()
try:
while True:
pc = sampler.getpc()
if pc in pcmap:
pcmap[pc] += 1
else:
pcmap[pc] = 1
func, addr = sampler.func(pc)
if not addr:
continue
if func in countmap:
countmap[func] += 1
total += 1
else:
countmap[func] = 1
total += 1
cur = time.time()
if cur - start > 1.0:
tmp = sorted(countmap.items(), key=operator.itemgetter(1), reverse=True)
for k, v in tmp:
# print('{:05.2f}% {}'.format((v * 100.) / total, k))
print('{:06.2f} clocks : {}'.format((v * 8192) / total, k))
start = cur
print('{} Samples'.format(total))
print('')
except KeyboardInterrupt:
pcmap = sorted(pcmap.items(), key=operator.itemgetter(1), reverse=True)
pcmap = [(hex(addr), count) for addr, count in pcmap]
+1 -1
View File
@@ -5,7 +5,7 @@ import numpy as np
Rload = 3300
R_25 = 10000
T_25 = 25 + 273.15 #Kelvin
Beta = 3380
Beta = 3434
Tmin = 0
Tmax = 140

Some files were not shown because too many files have changed in this diff Show More