mirror of
https://github.com/odriverobotics/ODrive.git
synced 2026-08-18 18:20:15 +08:00
Merge branch 'devel' into Endstops
This commit is contained in:
+27
-2
@@ -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();
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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,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_, ¤t_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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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", ¤t_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),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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_;
|
||||
|
||||
|
||||
@@ -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", ¤t_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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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", ¤t_control_.final_v_beta),
|
||||
make_protocol_property("Iq_setpoint", ¤t_control_.Iq_setpoint),
|
||||
make_protocol_property("Iq_measured", ¤t_control_.Iq_measured),
|
||||
make_protocol_property("max_allowed_current", ¤t_control_.max_allowed_current)
|
||||
make_protocol_ro_property("max_allowed_current", ¤t_control_.max_allowed_current),
|
||||
make_protocol_ro_property("overcurrent_trip_level", ¤t_control_.overcurrent_trip_level)
|
||||
),
|
||||
make_protocol_object("gate_driver",
|
||||
make_protocol_ro_property("drv_fault", &drv_fault_)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'}}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
@@ -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
Reference in New Issue
Block a user