00001
00043 #include "dc_motor.h"
00044 #include "hw/hw_dc_motor.h"
00045
00046
00047 #define LOG_LEVEL DC_MOTOR_LOG_LEVEL
00048 #define LOG_VERBOSITY DC_MOTOR_LOG_FORMAT
00049
00050 #include <cfg/log.h>
00051 #include <cfg/debug.h>
00052
00053 #include <algo/pid_control.h>
00054
00055 #include <drv/timer.h>
00056 #include <drv/adc.h>
00057
00058 #include <kern/proc.h>
00059
00060 #include <string.h>
00061
00065 static DCMotor dcm_all[CONFIG_NUM_DC_MOTOR];
00066
00068 static cpu_stack_t dc_motor_poll_stack[1024];
00069
00071 static mtime_t sample_period;
00072
00073
00074 LOG_INFOB(static int debug_msg_delay = 0;);
00075
00076
00077 static void dc_motor_do(int index);
00078
00093 static void NORETURN dc_motor_poll(void)
00094 {
00095 for (;;)
00096 {
00097 mtime_t max_sample_delay = 0;
00098 int i;
00099
00100
00101
00102
00103
00104 for (i = 0; i < CONFIG_NUM_DC_MOTOR; i++)
00105 {
00106 dc_motor_do(i);
00107 max_sample_delay = MAX(max_sample_delay, dcm_all[i].cfg->sample_delay);
00108 }
00109
00110
00111 timer_delay(sample_period - max_sample_delay);
00112
00113 for (i = 0; i < CONFIG_NUM_DC_MOTOR; i++)
00114 {
00115 if (dcm_all[i].status & DC_MOTOR_ACTIVE)
00116 {
00117 DC_MOTOR_DISABLE(dcm_all[i].index);
00118 pwm_enable(dcm_all[i].cfg->pwm_dev, false);
00119 }
00120 }
00121
00122
00123 timer_delay(max_sample_delay);
00124 }
00125 }
00126
00127
00128
00129
00130
00131 static void dc_motor_do(int index)
00132 {
00133 DCMotor *dcm = &dcm_all[index];
00134
00135 dc_speed_t curr_pos;
00136 pwm_duty_t new_pid;
00137
00138
00139 if (!(dcm->status & DC_MOTOR_ACTIVE))
00140 return;
00141
00142
00143 curr_pos = ADC_RANGECONV(adc_read(dcm->cfg->adc_ch), dcm->cfg->adc_min, dcm->cfg->adc_max);
00144
00145
00146 new_pid = pid_control_update(&dcm->pid_ctx, dcm->tgt_speed, curr_pos);
00147
00148
00149 LOG_INFOB(if (debug_msg_delay == 20)
00150 {
00151 LOG_INFO("DCmt[%d]>curr_speed[%d],tgt[%d]\n", dcm->index, curr_pos, dcm->tgt_speed);
00152 LOG_INFO("%d,", curr_pos);
00153 debug_msg_delay = 0;
00154 }
00155 debug_msg_delay++;
00156 kputs("\n"););
00157
00158 LOG_WARN("tg[%d], new_pid[%d], pos[%d]\n", dcm->tgt_speed, new_pid, curr_pos);
00159
00160
00161 pwm_setDuty(dcm->cfg->pwm_dev, new_pid);
00162
00163
00164 pwm_enable(dcm->cfg->pwm_dev, true);
00165
00166 DC_MOTOR_ENABLE(dcm->index);
00167 }
00168
00175 void dc_motor_setDir(int index, bool dir)
00176 {
00177 DCMotor *dcm = &dcm_all[index];
00178
00179 if (dir != (dcm->status & DC_MOTOR_DIR))
00180 {
00181
00182 dcm->status &= ~DC_MOTOR_DIR;
00183 dcm->status |= DC_MOTOR_DIR;
00184
00185
00186
00187
00188
00189 pwm_setPolarity(dcm->cfg->pwm_dev, dir);
00190 DC_MOTOR_SET_DIR(index, dir);
00191 }
00192 }
00193
00194
00198 void dc_motor_setSpeed(int index, dc_speed_t speed)
00199 {
00200 dcm_all[index].tgt_speed = speed;
00201 }
00202
00206 void dc_motor_enable(int index, bool state)
00207 {
00208 DCMotor *dcm = &dcm_all[index];
00209
00210
00211
00212
00213
00214 pid_control_reset(&dcm->pid_ctx);
00215
00216 if (state)
00217 {
00218 dcm->status |= DC_MOTOR_ACTIVE;
00219 }
00220 else
00221 {
00222 pwm_enable(dcm->cfg->pwm_dev, false);
00223 DC_MOTOR_DISABLE(dcm->index);
00224
00225 dcm->status &= ~DC_MOTOR_ACTIVE;
00226 }
00227 }
00228
00232 void dc_motor_setup(int index, DCMotorConfig *dcm_conf)
00233 {
00234 DCMotor *dcm = &dcm_all[index];
00235
00236 dcm->cfg = dcm_conf;
00237
00238
00239
00240
00241 dcm->index = index;
00242
00243 pwm_setFrequency(dcm->cfg->pwm_dev, dcm->cfg->freq);
00244 pwm_setPolarity(dcm->cfg->pwm_dev, dcm->cfg->pol);
00245 pwm_enable(dcm->cfg->pwm_dev, false);
00246
00247
00248 pid_control_init(&dcm->pid_ctx, &dcm->cfg->pid_cfg);
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 if (!sample_period)
00262 sample_period = dcm->cfg->pid_cfg.sample_period;
00263
00264 ASSERT(sample_period == dcm->cfg->pid_cfg.sample_period);
00265
00266
00267 DC_MOTOR_SET_DIR(dcm->index, dcm->cfg->dir);
00268
00269 LOG_INFO("DC motort[%d]:\n", dcm->index);
00270 LOG_INFO("> PID: kp[%lf],ki[%lf],kd[%lf]\n", dcm->cfg->pid_cfg.kd, dcm->cfg->pid_cfg.ki, dcm->cfg->pid_cfg.kd);
00271 LOG_INFO("> PWM: pwm_dev[%d], freq[%ld], sample[%ld]\n", dcm->cfg->pwm_dev, dcm->cfg->freq, dcm->cfg->sample_delay);
00272 LOG_INFO("> ADC: adc_ch[%d], adc_max[%d], adc_min[%d]\n", dcm->cfg->adc_ch, dcm->cfg->adc_max, dcm->cfg->adc_min);
00273 LOG_INFO("> DC: dir[%d], speed[%d]\n", dcm->cfg->dir, dcm->cfg->speed);
00274
00275 }
00276
00277
00281 void dc_motor_init(void)
00282 {
00283 memset(dcm_all, 0, sizeof(dcm_all));
00284
00285
00286 sample_period = 0;
00287
00288 MOTOR_DC_INIT();
00289
00290
00291 proc_new(dc_motor_poll, NULL, sizeof(dc_motor_poll_stack), dc_motor_poll_stack);
00292
00293 }
00294