84 osThreadId defaultTaskHandle;
85 uint32_t defaultTaskBuffer[ 128 ];
86 osStaticThreadDef_t defaultTaskControlBlock;
87 osThreadId UART1TaskHandle;
88 uint32_t UART1TaskBuffer[ 128 ];
89 osStaticThreadDef_t UART1TaskControlBlock;
90 osThreadId UART2TaskHandle;
91 uint32_t UART2TaskBuffer[ 128 ];
92 osStaticThreadDef_t UART2TaskControlBlock;
93 osThreadId UART3TaskHandle;
94 uint32_t UART3TaskBuffer[ 128 ];
95 osStaticThreadDef_t UART3TaskControlBlock;
96 osThreadId UART4TaskHandle;
97 uint32_t UART4TaskBuffer[ 128 ];
98 osStaticThreadDef_t UART4TaskControlBlock;
99 osThreadId UART6TaskHandle;
100 uint32_t UART6TaskBuffer[ 128 ];
101 osStaticThreadDef_t UART6TaskControlBlock;
102 osThreadId IMUTaskHandle;
103 uint32_t IMUTaskBuffer[ 128 ];
104 osStaticThreadDef_t IMUTaskControlBlock;
105 osThreadId CommandTaskHandle;
106 uint32_t CommandTaskBuffer[ 512 ];
107 osStaticThreadDef_t CommandTaskControlBlock;
108 osThreadId RxTaskHandle;
109 uint32_t RxTaskBuffer[ 512 ];
110 osStaticThreadDef_t RxTaskControlBlock;
111 osThreadId TxTaskHandle;
112 uint32_t TxTaskBuffer[ 512 ];
113 osStaticThreadDef_t TxTaskControlBlock;
114 osMessageQId UART1_reqHandle;
115 uint8_t UART1_reqBuffer[ 16 *
sizeof(
UARTcmd_t ) ];
116 osStaticMessageQDef_t UART1_reqControlBlock;
117 osMessageQId UART2_reqHandle;
118 uint8_t UART2_reqBuffer[ 16 *
sizeof(
UARTcmd_t ) ];
119 osStaticMessageQDef_t UART2_reqControlBlock;
120 osMessageQId UART3_reqHandle;
121 uint8_t UART3_reqBuffer[ 16 *
sizeof(
UARTcmd_t ) ];
122 osStaticMessageQDef_t UART3_reqControlBlock;
123 osMessageQId UART4_reqHandle;
124 uint8_t UART4_reqBuffer[ 16 *
sizeof(
UARTcmd_t ) ];
125 osStaticMessageQDef_t UART4_reqControlBlock;
126 osMessageQId UART6_reqHandle;
127 uint8_t UART6_reqBuffer[ 16 *
sizeof(
UARTcmd_t ) ];
128 osStaticMessageQDef_t UART6_reqControlBlock;
130 uint8_t TXQueueBuffer[ 32 *
sizeof(
TXData_t ) ];
131 osStaticMessageQDef_t TXQueueControlBlock;
132 osMutexId PCUARTHandle;
133 osStaticMutexDef_t PCUARTControlBlock;
136 enum motorNames {MOTOR1, MOTOR2, MOTOR3, MOTOR4, MOTOR5,
137 MOTOR6, MOTOR7, MOTOR8, MOTOR9, MOTOR10,
138 MOTOR11, MOTOR12, MOTOR13, MOTOR14, MOTOR15,
139 MOTOR16, MOTOR17, MOTOR18
143 Motor6, Motor7, Motor8, Motor9, Motor10,
144 Motor11, Motor12, Motor13, Motor14, Motor15,
145 Motor16, Motor17, Motor18;
149 bool setupIsDone =
false;
150 static volatile uint32_t error;
154 void StartDefaultTask(
void const * argument);
165 void MX_FREERTOS_Init(
void);
175 void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize );
185 static StaticTask_t xIdleTaskTCBBuffer;
186 static StackType_t xIdleStack[configMINIMAL_STACK_SIZE];
188 void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
190 *ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer;
191 *ppxIdleTaskStackBuffer = &xIdleStack[0];
192 *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
199 void MX_FREERTOS_Init(
void) {
206 osMutexStaticDef(PCUART, &PCUARTControlBlock);
207 PCUARTHandle = osMutexCreate(osMutex(PCUART));
223 osThreadStaticDef(defaultTask, StartDefaultTask, osPriorityIdle, 0, 128, defaultTaskBuffer, &defaultTaskControlBlock);
224 defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
227 osThreadStaticDef(UART1Task,
StartUART1Task, osPriorityNormal, 0, 128, UART1TaskBuffer, &UART1TaskControlBlock);
228 UART1TaskHandle = osThreadCreate(osThread(UART1Task), NULL);
231 osThreadStaticDef(UART2Task,
StartUART2Task, osPriorityNormal, 0, 128, UART2TaskBuffer, &UART2TaskControlBlock);
232 UART2TaskHandle = osThreadCreate(osThread(UART2Task), NULL);
235 osThreadStaticDef(UART3Task,
StartUART3Task, osPriorityNormal, 0, 128, UART3TaskBuffer, &UART3TaskControlBlock);
236 UART3TaskHandle = osThreadCreate(osThread(UART3Task), NULL);
239 osThreadStaticDef(UART4Task,
StartUART4Task, osPriorityNormal, 0, 128, UART4TaskBuffer, &UART4TaskControlBlock);
240 UART4TaskHandle = osThreadCreate(osThread(UART4Task), NULL);
243 osThreadStaticDef(UART6Task,
StartUART6Task, osPriorityNormal, 0, 128, UART6TaskBuffer, &UART6TaskControlBlock);
244 UART6TaskHandle = osThreadCreate(osThread(UART6Task), NULL);
247 osThreadStaticDef(IMUTask,
StartIMUTask, osPriorityNormal, 0, 128, IMUTaskBuffer, &IMUTaskControlBlock);
248 IMUTaskHandle = osThreadCreate(osThread(IMUTask), NULL);
251 osThreadStaticDef(CommandTask,
StartCommandTask, osPriorityBelowNormal, 0, 512, CommandTaskBuffer, &CommandTaskControlBlock);
252 CommandTaskHandle = osThreadCreate(osThread(CommandTask), NULL);
255 osThreadStaticDef(RxTask,
StartRxTask, osPriorityRealtime, 0, 512, RxTaskBuffer, &RxTaskControlBlock);
256 RxTaskHandle = osThreadCreate(osThread(RxTask), NULL);
259 osThreadStaticDef(TxTask,
StartTxTask, osPriorityHigh, 0, 512, TxTaskBuffer, &TxTaskControlBlock);
260 TxTaskHandle = osThreadCreate(osThread(TxTask), NULL);
268 osMessageQStaticDef(UART1_req, 16,
UARTcmd_t, UART1_reqBuffer, &UART1_reqControlBlock);
269 UART1_reqHandle = osMessageCreate(osMessageQ(UART1_req), NULL);
272 osMessageQStaticDef(UART2_req, 16,
UARTcmd_t, UART2_reqBuffer, &UART2_reqControlBlock);
273 UART2_reqHandle = osMessageCreate(osMessageQ(UART2_req), NULL);
276 osMessageQStaticDef(UART3_req, 16,
UARTcmd_t, UART3_reqBuffer, &UART3_reqControlBlock);
277 UART3_reqHandle = osMessageCreate(osMessageQ(UART3_req), NULL);
280 osMessageQStaticDef(UART4_req, 16,
UARTcmd_t, UART4_reqBuffer, &UART4_reqControlBlock);
281 UART4_reqHandle = osMessageCreate(osMessageQ(UART4_req), NULL);
284 osMessageQStaticDef(UART6_req, 16,
UARTcmd_t, UART6_reqBuffer, &UART6_reqControlBlock);
285 UART6_reqHandle = osMessageCreate(osMessageQ(UART6_req), NULL);
288 osMessageQStaticDef(TXQueue, 32,
TXData_t, TXQueueBuffer, &TXQueueControlBlock);
297 void StartDefaultTask(
void const * argument)
353 &Motor5,&Motor6,&Motor7,&Motor8,&Motor9,&Motor10,&Motor11,&Motor12,
354 &Motor13,&Motor14,&Motor15,&Motor16,&Motor17,&Motor18};
357 for(uint8_t i = MOTOR1; i <= MOTOR18; i++) {
368 if(arrDynamixel[i]->_motorType ==
AX12ATYPE){
373 (Motorcmd[i]).motorHandle = arrDynamixel[i];
377 (Motorcmd[MOTOR1]).qHandle = UART2_reqHandle;
378 (Motorcmd[MOTOR2]).qHandle = UART2_reqHandle;
379 (Motorcmd[MOTOR3]).qHandle = UART2_reqHandle;
380 (Motorcmd[MOTOR4]).qHandle = UART4_reqHandle;
381 (Motorcmd[MOTOR5]).qHandle = UART4_reqHandle;
382 (Motorcmd[MOTOR6]).qHandle = UART4_reqHandle;
383 (Motorcmd[MOTOR7]).qHandle = UART1_reqHandle;
384 (Motorcmd[MOTOR8]).qHandle = UART1_reqHandle;
385 (Motorcmd[MOTOR9]).qHandle = UART1_reqHandle;
386 (Motorcmd[MOTOR10]).qHandle = UART6_reqHandle;
387 (Motorcmd[MOTOR11]).qHandle = UART6_reqHandle;
388 (Motorcmd[MOTOR12]).qHandle = UART6_reqHandle;
389 (Motorcmd[MOTOR13]).qHandle = UART3_reqHandle;
390 (Motorcmd[MOTOR14]).qHandle = UART3_reqHandle;
391 (Motorcmd[MOTOR15]).qHandle = UART3_reqHandle;
392 (Motorcmd[MOTOR16]).qHandle = UART3_reqHandle;
393 (Motorcmd[MOTOR17]).qHandle = UART3_reqHandle;
394 (Motorcmd[MOTOR18]).qHandle = UART3_reqHandle;
402 xTaskNotify(RxTaskHandle, 1UL, eNoAction);
403 xTaskNotify(TxTaskHandle, 1UL, eNoAction);
404 xTaskNotify(UART1TaskHandle, 1UL, eNoAction);
405 xTaskNotify(UART2TaskHandle, 1UL, eNoAction);
406 xTaskNotify(UART3TaskHandle, 1UL, eNoAction);
407 xTaskNotify(UART4TaskHandle, 1UL, eNoAction);
408 xTaskNotify(UART6TaskHandle, 1UL, eNoAction);
409 xTaskNotify(IMUTaskHandle, 1UL, eNoAction);
411 uint32_t numIterations = 0;
418 for(uint8_t i = 0; i < 18; i++){
419 uint8_t* ptr = (uint8_t*)&positions[i];
420 for(uint8_t j = 0; j < 4; j++){
426 if(numIterations % 100 == 0){
428 for(uint8_t i = MOTOR1; i <= MOTOR18; i++){
430 Motorcmd[i].
value = 1;
431 xQueueSend(Motorcmd[i].qHandle, &Motorcmd[i], 0);
437 for(i = MOTOR1; i <= MOTOR18; i++){
439 case MOTOR1: Motorcmd[i].
value = positions[i]*180/M_PI + 150;
441 case MOTOR2: Motorcmd[i].
value = positions[i]*180/M_PI + 150;
443 case MOTOR3: Motorcmd[i].
value = positions[i]*180/M_PI + 150;
445 case MOTOR4: Motorcmd[i].
value = -1*positions[i]*180/M_PI + 150;
447 case MOTOR5: Motorcmd[i].
value = -1*positions[i]*180/M_PI + 150;
449 case MOTOR6: Motorcmd[i].
value = -1*positions[i]*180/M_PI + 150;
451 case MOTOR7: Motorcmd[i].
value = -1*positions[i]*180/M_PI + 150;
453 case MOTOR8: Motorcmd[i].
value = -1*positions[i]*180/M_PI + 150;
455 case MOTOR9: Motorcmd[i].
value = positions[i]*180/M_PI + 150;
457 case MOTOR10: Motorcmd[i].
value = -1*positions[i]*180/M_PI + 150;
459 case MOTOR11: Motorcmd[i].
value = -1*positions[i]*180/M_PI + 150;
461 case MOTOR12: Motorcmd[i].
value = positions[i]*180/M_PI + 150;
463 case MOTOR13: Motorcmd[i].
value = positions[i]*180/M_PI + 150;
465 case MOTOR14: Motorcmd[i].
value = positions[i]*180/M_PI + 60;
467 case MOTOR15: Motorcmd[i].
value = -1*positions[i]*180/M_PI + 150;
469 case MOTOR16: Motorcmd[i].
value = -1*positions[i]*180/M_PI + 240;
471 case MOTOR17: Motorcmd[i].
value = -1*positions[i]*180/M_PI + 150;
473 case MOTOR18: Motorcmd[i].
value = -1*positions[i]*180/M_PI + 150;
480 xQueueSend(Motorcmd[i].qHandle, &Motorcmd[i], 0);
485 xQueueSend(Motorcmd[i].qHandle, &Motorcmd[i], 0);
510 xTaskNotifyWait(UINT32_MAX, UINT32_MAX, NULL, portMAX_DELAY);
518 while(xQueueReceive(UART1_reqHandle, &cmdMessage, portMAX_DELAY) != pdTRUE);
540 xTaskNotifyWait(UINT32_MAX, UINT32_MAX, NULL, portMAX_DELAY);
548 while(xQueueReceive(UART2_reqHandle, &cmdMessage, portMAX_DELAY) != pdTRUE);
570 xTaskNotifyWait(UINT32_MAX, UINT32_MAX, NULL, portMAX_DELAY);
578 while(xQueueReceive(UART3_reqHandle, &cmdMessage, portMAX_DELAY) != pdTRUE);
600 xTaskNotifyWait(UINT32_MAX, UINT32_MAX, NULL, portMAX_DELAY);
608 while(xQueueReceive(UART4_reqHandle, &cmdMessage, portMAX_DELAY) != pdTRUE);
630 xTaskNotifyWait(UINT32_MAX, UINT32_MAX, NULL, portMAX_DELAY);
639 while(xQueueReceive(UART6_reqHandle, &cmdMessage, portMAX_DELAY) != pdTRUE);
660 xTaskNotifyWait(UINT32_MAX, UINT32_MAX, NULL, portMAX_DELAY);
665 TickType_t xLastWakeTime;
666 xLastWakeTime = xTaskGetTickCount();
668 const TickType_t IMU_CYCLE_TIME_MS = 2;
677 vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(IMU_CYCLE_TIME_MS));
716 xTaskNotifyWait(UINT32_MAX, UINT32_MAX, NULL, portMAX_DELAY);
740 xTaskNotifyWait(UINT32_MAX, UINT32_MAX, NULL, portMAX_DELAY);
775 BaseType_t xHigherPriorityTaskWoken = pdFALSE;
777 portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
795 BaseType_t xHigherPriorityTaskWoken = pdFALSE;
796 if(huart == &huart5){
799 if(huart == &huart1){
802 else if(huart == &huart2){
805 else if(huart == &huart3){
808 else if(huart == &huart4){
811 else if(huart == &huart6){
814 portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
832 BaseType_t xHigherPriorityTaskWoken = pdFALSE;
833 if (huart == &huart5) {
836 if(huart == &huart1){
839 else if(huart == &huart2){
842 else if(huart == &huart3){
845 else if(huart == &huart4){
848 else if(huart == &huart6){
851 portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
868 error = HAL_UART_GetError(huart);
void AX12A_SetComplianceMargin(Dynamixel_HandleTypeDef *hdynamixel, uint8_t complianceMargin)
Sets both the CW and CCW compliance margin.
This file defines resources used throughout various parts of the system that engage in non-blocking I...
void waitForNotificationRX(void)
Waits until notified from ISR.
void AX12A_SetComplianceSlope(Dynamixel_HandleTypeDef *hdynamixel, uint8_t complianceSlope)
Sets both the CW and CCW compliance slope.
Organizes all the information relevant to a motor.
void Fill_Struct(IMUStruct *myStruct)
Fills an IMUStruct.
This is the data structure copied into the sensor queue, and read by the thread that sends data to th...
void initializeVars(void)
Initializes the private variables for StartRxTask.
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
This function is called whenever a transmission from a UART module is completed. For this program...
void Read_Gyroscope_Withoffset_IT()
Reads the gyroscope with interrupts and offsets.
osMessageQId TXQueueHandle
Header for the helper file used to aid StartTxTask() in freertos.cpp.
void StartTxTask(void const *argument)
This function is executed in the context of the TxTask thread. This thread is blocked until all senso...
The data structure which represents the data of the IMU, which is sent in queues between tasks...
void shiftNotificationMask(void)
Shifts bits of NOTIFICATION_MASK.
void transmitStatusFromPC(void)
Makes calls to the UART module responsible for PC communication atomic.
void Dynamixel_Init(Dynamixel_HandleTypeDef *hdynamixel, uint8_t ID, UART_HandleTypeDef *UART_Handle, GPIO_TypeDef *DataDirPort, uint16_t DataDirPinNum, enum motorTypes_e motorType)
Initializes a motor handle.
void initiateDMATransfer(void)
Initiates DMA receive transfer using DMA.
void init(uint8_t lpf)
This function is used to initialize all aspects of the IMU which require I/O.
Header code for IMU filtering.
void Dynamixel_SetReturnDelayTime(Dynamixel_HandleTypeDef *hdynamixel, uint16_t microSec)
Sets the time, in microseconds, that the motor should wait before returning a status packet...
void StartCommandTask(void const *argument)
This function is executed in the context of the commandTask thread. It initializes all data structure...
void StartUART3Task(void const *argument)
This function is executed in the context of the UART3_ thread. It processes all commands for the moto...
#define NOTIFIED_FROM_TX_ISR
void updateStatusToPC(void)
Makes calls to the UART module responsible for PC communication atomic.
void StartUART2Task(void const *argument)
This function is executed in the context of the UART2_ thread. It processes all commands for the moto...
#define NOTIFIED_FROM_RX_ISR
void MPUFilter_InitAllFilters()
Initialize acceleration and angular velocity FIR filters for IMU data.
void StartIMUTask(void const *argument)
This function is executed in the context of the IMUTask thread. During each control cycle...
void StartRxTask(void const *argument)
This function is executed in the context of the RxTask thread. It initiates DMA-based receptions of R...
Header for top-level communication module.
void StartUART1Task(void const *argument)
This function is executed in the context of the UART1_ thread. It processes all commands for the moto...
void receiveDataBuffer(void)
Reads the received data buffer.
void Dynamixel_TorqueEnable(Dynamixel_HandleTypeDef *hdynamixel, uint8_t isEnabled)
Enables or disables torque for current motor.
void StartUART6Task(void const *argument)
This function is executed in the context of the UART6_ thread. It processes all commands for the moto...
void copySensorDataToSend(void)
Validates and copies sensor data to transmit.
Header file for the UART event processor, which is called whenever there are commands that need to be...
#define NOTIFIED_FROM_TASK
void StartUART4Task(void const *argument)
This function is executed in the context of the UART4_ thread. It processes all commands for the moto...
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
This function is called whenever an error is encountered in association with a UART module...
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
This function is called whenever a reception from a UART module is completed. For this program...
void Dynamixel_SetStatusReturnLevel(Dynamixel_HandleTypeDef *hdynamixel, uint8_t status_data)
Sets the conditions under which a status packet will be returned.
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c)
This function is called whenever a memory read from a I2C device is completed. For this program...
Header for the helper file used to aid StartRXTask() in freertos.cpp.
void UART_ProcessEvent(UARTcmd_t *cmdPtr, TXData_t *DataToSend)
The UART event processor calls the low-level libraries to execute reads and writes for motors...
void Dynamixel_SetIOType(enum IO_FLAGS type)
Sets the I/O type used by the library.
Header code for the MPU6050 class.
void waitForNotificationTX(void)
Waits until notified from ISR.
Common header code for the AX12A library and MX28 library. It is generic in that any Dynamixel actuat...
The container type for motor commands. The control thread sends these to the various UART handlers th...
void Read_Accelerometer_Withoffset_IT()
Reads the accelerometer with interrupts and offsets.