From 4bb6bbb21f61e56e42b63a921e65b79f56a41566 Mon Sep 17 00:00:00 2001
From: Charles <charles.sirois14@gmail.com>
Date: Sun, 16 Feb 2020 14:27:23 -0500
Subject: [PATCH] bsp motor

---
 Algorithm/pid.c  |  62 +++++++++++++++++++++++++++
 Algorithm/pid.h  |  50 ++++++++++++++++++++++
 Device/motor.c   |   0
 Device/motor.h   |   0
 Driver/bsp_can.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++
 Driver/bsp_can.h |  40 ++++++++++++++++++
 Driver/bsp_key.c |  40 ++++++++++++++++++
 Driver/bsp_key.h |  24 +++++++++++
 Driver/bsp_led.h |  31 ++++++++++++++
 9 files changed, 353 insertions(+)
 create mode 100644 Algorithm/pid.c
 create mode 100644 Algorithm/pid.h
 create mode 100644 Device/motor.c
 create mode 100644 Device/motor.h
 create mode 100644 Driver/bsp_can.c
 create mode 100644 Driver/bsp_can.h
 create mode 100644 Driver/bsp_key.c
 create mode 100644 Driver/bsp_key.h
 create mode 100644 Driver/bsp_led.h

diff --git a/Algorithm/pid.c b/Algorithm/pid.c
new file mode 100644
index 0000000..bd4e3f8
--- /dev/null
+++ b/Algorithm/pid.c
@@ -0,0 +1,62 @@
+/****************************************************************************
+ *  Copyright (C) 2018 RoboMaster.
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program. If not, see <http://www.gnu.org/licenses/>.
+ ***************************************************************************/
+ 
+#include "pid.h"
+
+/**
+  * @brief  init pid parameter
+  * @param  pid struct
+    @param  parameter
+  * @retval None
+  */
+void pid_init(pid_struct_t *pid,
+              float kp,
+              float ki,
+              float kd,
+              float i_max,
+              float out_max)
+{
+  pid->kp      = kp;
+  pid->ki      = ki;
+  pid->kd      = kd;
+  pid->i_max   = i_max;
+  pid->out_max = out_max;
+}
+
+/**
+  * @brief  pid calculation
+  * @param  pid struct
+    @param  reference value
+    @param  feedback value
+  * @retval calculation result
+  */
+float pid_calc(pid_struct_t *pid, float ref, float fdb)
+{
+  pid->ref = ref;
+  pid->fdb = fdb;
+  pid->err[1] = pid->err[0];
+  pid->err[0] = pid->ref - pid->fdb;
+  
+  pid->p_out  = pid->kp * pid->err[0];
+  pid->i_out += pid->ki * pid->err[0];
+  pid->d_out  = pid->kd * pid->err[0] - pid->err[1];
+  LIMIT_MIN_MAX(pid->i_out, -pid->i_max, pid->i_max);
+  
+  pid->output = pid->p_out + pid->i_out + pid->d_out;
+  LIMIT_MIN_MAX(pid->output, -pid->out_max, pid->out_max);
+  return pid->output;
+}
diff --git a/Algorithm/pid.h b/Algorithm/pid.h
new file mode 100644
index 0000000..69f6f47
--- /dev/null
+++ b/Algorithm/pid.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+ *  Copyright (C) 2018 RoboMaster.
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program. If not, see <http://www.gnu.org/licenses/>.
+ ***************************************************************************/
+ 
+#ifndef _PID_H
+#define _PID_H
+
+#include "main.h"
+
+typedef struct _pid_struct_t
+{
+  float kp;
+  float ki;
+  float kd;
+  float i_max;
+  float out_max;
+  
+  float ref;      // target value
+  float fdb;      // feedback value
+  float err[2];   // error and last error
+
+  float p_out;
+  float i_out;
+  float d_out;
+  float output;
+}pid_struct_t;
+
+void pid_init(pid_struct_t *pid,
+              float kp,
+              float ki,
+              float kd,
+              float i_max,
+              float out_max);
+              
+float  pid_calc(pid_struct_t *pid, float ref, float fdb);
+
+#endif
diff --git a/Device/motor.c b/Device/motor.c
new file mode 100644
index 0000000..e69de29
diff --git a/Device/motor.h b/Device/motor.h
new file mode 100644
index 0000000..e69de29
diff --git a/Driver/bsp_can.c b/Driver/bsp_can.c
new file mode 100644
index 0000000..0df7811
--- /dev/null
+++ b/Driver/bsp_can.c
@@ -0,0 +1,106 @@
+/****************************************************************************
+ *  Copyright (C) 2018 RoboMaster.
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program. If not, see <http://www.gnu.org/licenses/>.
+ ***************************************************************************/
+ 
+#include "bsp_can.h"
+#include "bsp_led.h"
+
+moto_info_t motor_info[MOTOR_MAX_NUM];
+uint16_t can_cnt;
+
+/**
+  * @brief  init can filter, start can, enable can rx interrupt
+  * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
+  *         the configuration information for the specified CAN.
+  * @retval None
+  */
+void can_user_init(CAN_HandleTypeDef* hcan )
+{
+  CAN_FilterTypeDef  can_filter;
+
+  can_filter.FilterBank = 0;                       // filter 0
+  can_filter.FilterMode =  CAN_FILTERMODE_IDMASK;  // mask mode
+  can_filter.FilterScale = CAN_FILTERSCALE_32BIT;
+  can_filter.FilterIdHigh = 0;
+  can_filter.FilterIdLow  = 0;
+  can_filter.FilterMaskIdHigh = 0;
+  can_filter.FilterMaskIdLow  = 0;                // set mask 0 to receive all can id
+  can_filter.FilterFIFOAssignment = CAN_RX_FIFO0; // assign to fifo0
+  can_filter.FilterActivation = ENABLE;           // enable can filter
+  can_filter.SlaveStartFilterBank  = 14;          // only meaningful in dual can mode
+   
+  HAL_CAN_ConfigFilter(hcan, &can_filter);        // init can filter
+  HAL_CAN_Start(&hcan1);                          // start can1
+  HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING); // enable can1 rx interrupt
+}
+
+/**
+  * @brief  can rx callback, get motor feedback info
+  * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
+  *         the configuration information for the specified CAN.
+  * @retval None
+  */
+void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
+{
+  CAN_RxHeaderTypeDef rx_header;
+  uint8_t             rx_data[8];
+  if(hcan->Instance == CAN1)
+  {
+    HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, rx_data); //receive can data
+  }
+  if ((rx_header.StdId >= FEEDBACK_ID_BASE)
+   && (rx_header.StdId <  FEEDBACK_ID_BASE + MOTOR_MAX_NUM))                  // judge the can id
+  {
+    can_cnt ++;
+    uint8_t index = rx_header.StdId - FEEDBACK_ID_BASE;                  // get motor index by can_id
+    motor_info[index].rotor_angle    = ((rx_data[0] << 8) | rx_data[1]);
+    motor_info[index].rotor_speed    = ((rx_data[2] << 8) | rx_data[3]);
+    motor_info[index].torque_current = ((rx_data[4] << 8) | rx_data[5]);
+    motor_info[index].temp           =   rx_data[6];
+  }
+  if (can_cnt == 500)
+  {
+    can_cnt = 0;
+    LED_GREEN_TOGGLE(); // green led blink indicate can comunication successful 
+  }
+}
+
+/**
+  * @brief  send motor control message through can bus
+  * @param  id_range to select can control id 0x1ff or 0x2ff
+  * @param  motor voltage 1,2,3,4 or 5,6,7
+  * @retval None
+  */
+void set_motor_voltage(uint8_t id_range, int16_t v1, int16_t v2, int16_t v3, int16_t v4)
+{
+  CAN_TxHeaderTypeDef tx_header;
+  uint8_t             tx_data[8];
+    
+  tx_header.StdId = (id_range == 0)?(0x200):(0x1ff);
+  tx_header.IDE   = CAN_ID_STD;
+  tx_header.RTR   = CAN_RTR_DATA;
+  tx_header.DLC   = 8;
+
+  tx_data[0] = (v1>>8)&0xff;
+  tx_data[1] =    (v1)&0xff;
+  tx_data[2] = (v2>>8)&0xff;
+  tx_data[3] =    (v2)&0xff;
+  tx_data[4] = (v3>>8)&0xff;
+  tx_data[5] =    (v3)&0xff;
+  tx_data[6] = (v4>>8)&0xff;
+  tx_data[7] =    (v4)&0xff;
+  HAL_CAN_AddTxMessage(&hcan1, &tx_header, tx_data,(uint32_t*)CAN_TX_MAILBOX0); 
+}
diff --git a/Driver/bsp_can.h b/Driver/bsp_can.h
new file mode 100644
index 0000000..04cee92
--- /dev/null
+++ b/Driver/bsp_can.h
@@ -0,0 +1,40 @@
+/****************************************************************************
+ *  Copyright (C) 2018 RoboMaster.
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program. If not, see <http://www.gnu.org/licenses/>.
+ ***************************************************************************/
+
+#ifndef __BSP_CAN
+#define __BSP_CAN
+
+#include "can.h"
+
+#define FEEDBACK_ID_BASE      0x201
+#define CAN_CONTROL_ID_BASE   0x200
+#define CAN_CONTROL_ID_EXTEND 0x1ff
+#define MOTOR_MAX_NUM         7
+
+typedef struct
+{
+    uint16_t can_id;
+    int16_t  set_voltage;
+    uint16_t rotor_angle;
+    int16_t  rotor_speed;
+    int16_t  torque_current;
+    uint8_t  temp;
+}moto_info_t;
+
+void can_user_init(CAN_HandleTypeDef* hcan);
+void set_motor_voltage(uint8_t id_range, int16_t v1, int16_t v2, int16_t v3, int16_t v4);
+#endif
diff --git a/Driver/bsp_key.c b/Driver/bsp_key.c
new file mode 100644
index 0000000..afbef13
--- /dev/null
+++ b/Driver/bsp_key.c
@@ -0,0 +1,40 @@
+/****************************************************************************
+ *  Copyright (C) 2018 RoboMaster.
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program. If not, see <http://www.gnu.org/licenses/>.
+ ***************************************************************************/
+ 
+#include "bsp_key.h"
+
+/**
+  * @brief  detect key presse down event
+  * @param  None
+  * @retval event flag
+  */
+uint8_t key_scan(void)
+{
+  static uint8_t key_last = 0;
+  static uint8_t key = 0;
+  
+  key_last = key;
+  key = HAL_GPIO_ReadPin(KEY_GPIO_Port,KEY_Pin);
+  if( (key == GPIO_PIN_RESET) && (key_last == GPIO_PIN_SET))
+  {
+    return 1;
+  }
+  else
+  {
+    return 0;
+  }
+}
\ No newline at end of file
diff --git a/Driver/bsp_key.h b/Driver/bsp_key.h
new file mode 100644
index 0000000..00ca3f2
--- /dev/null
+++ b/Driver/bsp_key.h
@@ -0,0 +1,24 @@
+/****************************************************************************
+ *  Copyright (C) 2018 RoboMaster.
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program. If not, see <http://www.gnu.org/licenses/>.
+ ***************************************************************************/
+
+#ifndef __BSP_KEY
+#define __BSP_KEY
+
+#include "gpio.h"
+
+uint8_t key_scan(void);
+#endif
diff --git a/Driver/bsp_led.h b/Driver/bsp_led.h
new file mode 100644
index 0000000..b4181c4
--- /dev/null
+++ b/Driver/bsp_led.h
@@ -0,0 +1,31 @@
+/****************************************************************************
+ *  Copyright (C) 2018 RoboMaster.
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program. If not, see <http://www.gnu.org/licenses/>.
+ ***************************************************************************/
+ 
+#ifndef __BSP_LED
+#define __BSP_LED
+
+#define LED_GREEN_ON()     HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET)
+#define LED_GREEN_OFF()    HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_SET)
+#define LED_GREEN_TOGGLE() LED_GREEN_GPIO_Port->ODR ^= LED_GREEN_Pin
+     
+#define LED_RED_ON()       HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_RESET)
+#define LED_RED_OFF()      HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_SET)
+#define LED_RED_TOGGLE()   LED_RED_GPIO_Port->ODR ^= LED_RED_Pin
+     
+#define LED_ALL_OFF        LED_RED_OFF(); LED_RED_OFF();
+
+#endif
-- 
GitLab