MotorController
motor.c
1 #include "motor.h"
2 
3 #define RCC_TIM17EN 0x00040000
4 #define RCC_TIM17RST 0x00040000
5 
6 /*
7  * Rotation sense for forward and backward movements, for each motor.
8  * MOTOR_LEFT
9  * |-----FORWARD -> ??
10  * |-----BACKWARD -> ??
11  * MOTOR_RIGHT
12  * |-----FORWARD -> ??
13  * |-----BACKWARD -> ??
14  */
15 static motor_sense_t rotation_direction[2][2];
16 
17 /*
18  * Current direction for each motor (FORWARD or BACKWARD).
19  */
20 static motor_direction_t motor_direction[2];
21 
22 /*
23  * Pin allocation for each motor.
24  */
25 static const uint8_t pin_A[2] = {GPIOA_RMOTA, GPIOA_LMOTA};
26 static const uint8_t pin_B[2] = {GPIOA_RMOTB, GPIOA_LMOTB};
27 
28 static int8_t left_speed = 0U;
29 static int8_t right_speed = 0U;
30 
31 #define PWM_FREQUENCY_KHZ 20
32 #define CLK_KHZ 72000
33 
34 static PWMConfig pwm_config_tim2 = {
35  PWM_FREQUENCY_KHZ * MAX_COMMAND * 1000U,
37  NULL,
38  {
39  {PWM_OUTPUT_DISABLED, NULL},
40  {PWM_OUTPUT_DISABLED, NULL},
41  {PWM_OUTPUT_ACTIVE_HIGH, NULL},
42  {PWM_OUTPUT_DISABLED, NULL}
43  },
44  0,
45  0
46 };
47 
48 extern void motor_init(motor_sense_t motor_left_forward_sense, motor_sense_t motor_right_forward_sense) {
49 
50  /* Start PWM TIM 2 */
51  pwmStart(&PWMD2, &pwm_config_tim2);
52 
53  /* Start PWM TIM17 */
54  rccEnableAPB2(RCC_TIM17EN, FALSE);
55  TIM17->CCER = 0x00; // disable capture/compare during setup
56  TIM17->CR2 = 0x00;
57  TIM17->BDTR = 0x8C00; // enable outputs
58  TIM17->DIER = 0x00; // disable DMA and interrupts
59  TIM17->CCMR1 = 0x68; // PWM mode 1 on channel 1
60  TIM17->ARR = MAX_COMMAND;
61  TIM17->PSC = CLK_KHZ/(PWM_FREQUENCY_KHZ * MAX_COMMAND) - 1; // setup prescaler
62  TIM17->CCR1 = 0; // turn off motors at startup
63  TIM17->CCER = 0x01; // enable CC1
64  TIM17->EGR = 0x01; // generate an update event to load the setup values
65  TIM17->CNT = 0;
66  TIM17->CR1 = 0x81; // enable counter
67 
68  rotation_direction[MOTOR_LEFT][FORWARD] = motor_left_forward_sense;
69  rotation_direction[MOTOR_LEFT][BACKWARD] = DIRECTION_2 - motor_left_forward_sense;
70  rotation_direction[MOTOR_RIGHT][FORWARD] = motor_right_forward_sense;
71  rotation_direction[MOTOR_RIGHT][BACKWARD] = DIRECTION_2 - motor_right_forward_sense;
72 
75 }
76 
77 extern int motor_set_speed(motor_t motor, uint8_t speed) {
78  int status;
79 
80  if ((motor != MOTOR_LEFT) && (motor != MOTOR_RIGHT)) {
81  status = -1;
82  } else if (speed > MAX_COMMAND) {
83  status = -2;
84  } else {
85  switch(motor)
86  {
87  case MOTOR_LEFT:
88  pwmEnableChannel(&PWMD2, 2, speed);
89  left_speed = speed;
90  break;
91  case MOTOR_RIGHT:
92  TIM17->CCR1 = speed;
93  right_speed = speed;
94  break;
95  default:
96  break;
97  }
98  status = 0;
99  }
100  return status;
101 }
102 
103 extern int8_t motor_get_speed(motor_t motor) {
104  switch (motor) {
105  case MOTOR_LEFT:
106  return left_speed;
107  case MOTOR_RIGHT:
108  return right_speed;
109  default:
110  return -1;
111  }
112 }
113 
115 {
116  if ((motor != MOTOR_LEFT) && (motor != MOTOR_RIGHT)) {
117  return (motor_direction_t)-1;
118  } else{
119  return motor_direction[motor];
120  }
121 }
122 
123 extern int motor_set_direction(motor_t motor, motor_direction_t direction)
124 {
125  int status;
126  if ((motor != MOTOR_LEFT) && (motor != MOTOR_RIGHT)) {
127  status = -1;
128  } else if ((direction != FORWARD) && (direction != BACKWARD)) {
129  status = -2;
130  } else {
131  motor_direction[motor] = direction;
132 
133  if (rotation_direction[motor][direction] == DIRECTION_1) {
134  palSetPad(GPIOA, pin_A[motor]);
135  palClearPad(GPIOA, pin_B[motor]);
136  } else {
137  palClearPad(GPIOA, pin_A[motor]);
138  palSetPad(GPIOA, pin_B[motor]);
139  }
140  status = 0;
141  }
142  return status;
143 }
144 
145 extern void motor_toggle_direction(motor_t motor)
146 {
147  if (motor_direction[motor] == FORWARD) {
149  } else {
151  }
152 }
int motor_set_speed(motor_t motor, uint8_t speed)
Set the rotation speed of the specified motor.
Definition: motor.c:77
int motor_set_direction(motor_t motor, motor_direction_t direction)
Set the rotation direction of the specified motor.
Definition: motor.c:123
motor_direction_t
Alias for motor rotation sense.
Definition: motor.h:28
Definition: motor.h:30
motor_t
Alias to select the motor to work on.
Definition: motor.h:20
motor_sense_t
Alias for motor orientation.
Definition: motor.h:40
void motor_init(motor_sense_t motor_left_forward_sense, motor_sense_t motor_right_forward_sense)
Initialise the motor driver.
Definition: motor.c:48
void motor_toggle_direction(motor_t motor)
Revert the rotation direction of the specified motor.
Definition: motor.c:145
int8_t motor_get_speed(motor_t motor)
Get the rotation speed of the specified motor.
Definition: motor.c:103
Definition: motor.h:29
#define MAX_COMMAND
Definition: motor.h:11
motor_direction_t motor_get_direction(motor_t motor)
Get the current rotation direction of the specified motor.
Definition: motor.c:114