Skip to content

Commit 8f93fd2

Browse files
committed
draft
1 parent 88de695 commit 8f93fd2

File tree

12 files changed

+409
-513
lines changed

12 files changed

+409
-513
lines changed

stm32-modules/flex-stacker/firmware/motor_control/freertos_motor_driver_task.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "FreeRTOS.h"
44
#include "firmware/motor_hardware.h"
5+
#include "firmware/motor_driver_policy.hpp"
56
#include "flex-stacker/motor_driver_task.hpp"
67
#include "ot_utils/freertos/freertos_timer.hpp"
78

@@ -28,7 +29,9 @@ auto run(tasks::FirmwareTasks::QueueAggregator* aggregator) -> void {
2829

2930
spi_hardware_init();
3031

32+
auto policy = motor_driver_policy::MotorDriverPolicy();
3133
while (true) {
34+
_top_task.run_once(policy);
3235
}
3336
}
3437

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include "firmware/motor_driver_policy.hpp"
2+
3+
#include "firmware/motor_hardware.h"
4+
5+
6+
// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
7+
auto MotorDriverPolicy::tmc2160_transmit_receive(MotorID motor_id, tmc2160::MessageT& data) -> RxTxReturn {
8+
tmc2160::MessageT retBuf = {0};
9+
if (spi_dma_transmit_receive(motor_id, data.data(), retBuf.data(), data.size())) {
10+
return RxTxReturn(retBuf);
11+
}
12+
return RxTxReturn();
13+
}

stm32-modules/flex-stacker/firmware/motor_control/motor_policy.cpp

Lines changed: 0 additions & 13 deletions
This file was deleted.

stm32-modules/flex-stacker/firmware/motor_control/motor_spi_hardware.c

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55
#include "stm32g4xx_hal_gpio.h"
66
#include "stm32g4xx_hal_dma.h"
77

8+
#include "FreeRTOS.h"
9+
#include "task.h"
810
#include <stdbool.h>
911

12+
1013
/* SPI2 Pins */
1114
#define SPI2_SCK_Pin (GPIO_PIN_13)
1215
#define SPI2_CIPO_Pin (GPIO_PIN_14)
@@ -23,21 +26,29 @@
2326
#define nSPI2_NSS_L_Pin (GPIO_PIN_2)
2427
#define nSPI2_NSS_L_GPIO_Port (GPIOB)
2528

29+
/** Maximum length of a SPI transaction is 5 bytes.*/
30+
#define MOTOR_MAX_SPI_LEN (5)
31+
2632

2733
/** Static Variables -------------------------------------------------------- */
2834

2935
struct motor_spi_hardware {
3036
SPI_HandleTypeDef handle;
37+
TaskHandle_t task_to_notify;
3138
bool initialized;
3239
};
3340

41+
static void spi_interrupt_service(void);
42+
static void spi_set_nss(bool selected);
43+
3444

3545
DMA_HandleTypeDef hdma_spi2_rx;
3646
DMA_HandleTypeDef hdma_spi2_tx;
3747

3848

3949
static struct motor_spi_hardware _spi = {
4050
.handle = {0},
51+
.task_to_notify = NULL,
4152
.initialized = false
4253
};
4354

@@ -246,36 +257,60 @@ void SPI2_IRQHandler(void)
246257
HAL_SPI_IRQHandler(&_spi.handle);
247258
}
248259

260+
static void spi_interrupt_service(void) {
261+
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
262+
if( _spi.task_to_notify == NULL ) {
263+
return;
264+
}
265+
vTaskNotifyGiveFromISR( _spi.task_to_notify, &xHigherPriorityTaskWoken );
266+
_spi.task_to_notify = NULL;
267+
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
268+
}
269+
270+
249271
/**
250272
* @brief TxRx Transfer completed callback.
251273
*/
252274
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
253275
{
254-
// TODO: Implement this callback
276+
spi_interrupt_service();
255277
}
256278

257279
/**
258280
* @brief Spi Transfer Error callback.
259281
*/
260282
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
261283
{
262-
// TODO: Implement this callback
284+
spi_interrupt_service();
263285
}
264286

265-
void spi_dma_transmit_receive(
287+
bool tmc2160_transmit_receive(
266288
MotorID motor_id, uint8_t *txData, uint8_t *rxData, uint16_t size
267289
) {
290+
const TickType_t max_block_time = pdMS_TO_TICKS(100);
291+
HAL_StatusTypeDef ret;
292+
uint32_t notification_val = 0;
293+
294+
if (!_spi.initialized || (_spi.task_to_notify != NULL) || (size > MOTOR_MAX_SPI_LEN)) {
295+
return false;
296+
}
268297
// enable one of the motor driver for SPI communication
269298
enable_spi_nss(motor_id);
270-
299+
_spi.task_to_notify = xTaskGetCurrentTaskHandle();
271300
if (HAL_SPI_TransmitReceive_DMA(&_spi.handle, txData, rxData, size) != HAL_OK) {
272301
// Transmission error
273-
// TODO: implement error handling
302+
_spi.task_to_notify = NULL;
303+
return false;
274304
}
275-
276-
// Wait for the transmission to complete
277-
while (HAL_SPI_GetState(&_spi.handle) != HAL_SPI_STATE_READY) {}
278-
305+
notification_val = ulTaskNotifyTake(pdTRUE, max_block_time);
279306
disable_spi_nss();
307+
// If the task was preempted by the error handler rather than the
308+
// TxRx complete callback, the remaining count should be greater
309+
// than 0.
310+
if((notification_val != 1) || (_spi.handle.RxXferCount > 0)) {
311+
_spi.task_to_notify = NULL;
312+
return true;
313+
}
314+
return true;
280315
}
281316

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#pragma once
2+
3+
#include <optional>
4+
5+
#include "systemwide.h"
6+
#include "flex-stacker/tmc2160.hpp"
7+
8+
namespace motor_driver_policy {
9+
class MotorDriverPolicy {
10+
public:
11+
using RxTxReturn = std::optional<tmc2160::MessageT>;
12+
auto tmc2160_transmit_receive(MotorID motor_id, tmc2160::MessageT& data) -> RxTxReturn;
13+
};
14+
15+
} // namespace motor_driver_policy

stm32-modules/include/flex-stacker/firmware/motor_hardware.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@
44
extern "C" {
55
#endif // __cplusplus
66

7+
#include <stdbool.h>
78
#include <stdint.h>
89

910
#include "systemwide.h"
1011

1112
void motor_hardware_init(void);
1213

1314
void spi_hardware_init(void);
14-
void spi_dma_transmit_receive(MotorID motor_id, uint8_t *tx_data,
15+
bool spi_dma_transmit_receive(MotorID motor_id, uint8_t *tx_data,
1516
uint8_t *rx_data, uint16_t len);
1617

1718
#ifdef __cplusplus

stm32-modules/include/flex-stacker/firmware/motor_policy.hpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ class MotorPolicy {
1111
auto enable_motor(MotorID motor_id) -> void;
1212
auto disable_motor(MotorID motor_id) -> void;
1313
auto set_motor_speed(MotorID motor_id, double speed) -> bool;
14-
15-
auto spi_transmit_receive(MotorID motor_id, uint8_t *tx_data,
16-
uint8_t *rx_data, uint16_t len) -> void;
1714
};
15+
1816
} // namespace motor_policy

stm32-modules/include/flex-stacker/flex-stacker/motor_driver_task.hpp

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,34 @@
55
*/
66
#pragma once
77

8+
9+
#include "systemwide.h"
810
#include "core/ack_cache.hpp"
911
#include "core/queue_aggregator.hpp"
1012
#include "core/version.hpp"
13+
#include "firmware/motor_policy.hpp"
1114
#include "flex-stacker/messages.hpp"
1215
#include "flex-stacker/tasks.hpp"
16+
#include "flex-stacker/tmc2160.hpp"
17+
#include "flex-stacker/tmc2160_interface.hpp"
1318
#include "flex-stacker/tmc2160_registers.hpp"
1419
#include "hal/message_queue.hpp"
1520

1621
namespace motor_driver_task {
1722

23+
1824
using Message = messages::MotorDriverMessage;
1925

26+
2027
static constexpr tmc2160::TMC2160RegisterMap motor_z_config{
2128
.gconfig = {.diag0_error = 1, .diag1_stall = 1},
29+
.glob_scale = {.global_scaler = 0x8B},
2230
.ihold_irun = {.hold_current = 1,
2331
.run_current = 31,
2432
.hold_current_delay = 1},
33+
.tpwmthrs = {.threshold = 0x80000},
2534
.tcoolthrs = {.threshold = 0x81},
2635
.thigh = {.threshold = 0x81},
27-
.tpwmthrs = {.threshold = 0x80000},
2836
.chopconf = {.toff = 0b111,
2937
.hstrt = 0b100,
3038
.hend = 0b11,
@@ -37,17 +45,17 @@ static constexpr tmc2160::TMC2160RegisterMap motor_z_config{
3745
.pwm_autograd = 1,
3846
.pwm_reg = 4,
3947
.pwm_lim = 0xC},
40-
.glob_scale = {.global_scaler = 0x8B},
4148
};
4249

4350
static constexpr tmc2160::TMC2160RegisterMap motor_x_config{
4451
.gconfig = {.diag0_error = 1, .diag1_stall = 1},
52+
.glob_scale = {.global_scaler = 0x8B},
4553
.ihold_irun = {.hold_current = 1,
4654
.run_current = 31,
4755
.hold_current_delay = 1},
56+
.tpwmthrs = {.threshold = 0x80000},
4857
.tcoolthrs = {.threshold = 0x81},
4958
.thigh = {.threshold = 0x81},
50-
.tpwmthrs = {.threshold = 0x80000},
5159
.chopconf = {.toff = 0b111,
5260
.hstrt = 0b111,
5361
.hend = 0b1001,
@@ -60,17 +68,17 @@ static constexpr tmc2160::TMC2160RegisterMap motor_x_config{
6068
.pwm_autograd = 1,
6169
.pwm_reg = 4,
6270
.pwm_lim = 0xC},
63-
.glob_scale = {.global_scaler = 0x8B},
6471
};
6572

66-
static constexpr tmc2160::TMC2160RegisterMap motor_l_config{
73+
constexpr tmc2160::TMC2160RegisterMap motor_l_config{
6774
.gconfig = {.diag0_error = 1, .diag1_stall = 1},
75+
.glob_scale = {.global_scaler = 0x8B},
6876
.ihold_irun = {.hold_current = 1,
6977
.run_current = 31,
7078
.hold_current_delay = 1},
79+
.tpwmthrs = {.threshold = 0x80000},
7180
.tcoolthrs = {.threshold = 0x81},
7281
.thigh = {.threshold = 0x81},
73-
.tpwmthrs = {.threshold = 0x80000},
7482
.chopconf = {.toff = 0b111,
7583
.hstrt = 0b111,
7684
.hend = 0b1001,
@@ -83,7 +91,6 @@ static constexpr tmc2160::TMC2160RegisterMap motor_l_config{
8391
.pwm_autograd = 1,
8492
.pwm_reg = 4,
8593
.pwm_lim = 0xC},
86-
.glob_scale = {.global_scaler = 0x8B},
8794
};
8895

8996
template <template <class> class QueueImpl>
@@ -107,10 +114,24 @@ class MotorDriverTask {
107114
_task_registry = aggregator;
108115
}
109116

110-
auto run_once() -> void {
117+
template <tmc2160::TMC2160InterfacePolicy Policy>
118+
auto run_once(Policy& policy) -> void {
111119
if (!_task_registry) {
112120
return;
113121
}
122+
if (!_initialized) {
123+
124+
if (!_tmc2160.initialize_config(motor_z_config, tmc2160::TMC2160Interface(policy), MotorID::MOTOR_Z)) {
125+
return;
126+
}
127+
if (!_tmc2160.initialize_config(motor_x_config, tmc2160::TMC2160Interface(policy), MotorID::MOTOR_X)) {
128+
return;
129+
}
130+
if (!_tmc2160.initialize_config(motor_l_config, tmc2160::TMC2160Interface(policy), MotorID::MOTOR_L)) {
131+
return;
132+
}
133+
_initialized = true;
134+
}
114135

115136
auto message = Message(std::monostate());
116137

@@ -126,6 +147,7 @@ class MotorDriverTask {
126147
static_cast<void>(message);
127148
}
128149

150+
129151
auto visit_message(const messages::SetMotorDriverRegister& message) -> void {
130152
static_cast<void>(message);
131153
}
@@ -142,9 +164,14 @@ class MotorDriverTask {
142164
static_cast<void>(message);
143165
}
144166

167+
168+
145169
Queue& _message_queue;
146170
Aggregator* _task_registry;
147171
bool _initialized;
148-
};
149172

173+
tmc2160::TMC2160 _tmc2160{};
174+
tmc2160::TMC2160Interface<Policy>* _tmc2160_interface;
175+
176+
};
150177
}; // namespace motor_task

0 commit comments

Comments
 (0)