1 /*******************************************************************
2 Motion and Robotic System (MARS) aplication components.
4 appl_pxmc.c - position controller subsystem core generic
5 and LP_MPW1 hardware specific support
7 Copyright (C) 2001-2013 by Pavel Pisa - originator
9 (C) 2001-2013 by PiKRON Ltd. - originator
12 This file can be used and copied according to next
14 - GPL - GNU Public License
15 - other license provided by project originators
17 *******************************************************************/
20 #include <system_def.h>
22 #include <pxmc_lpc_qei.h>
23 #include <pxmc_internal.h>
24 #include <pxmc_inp_common.h>
25 #include <pxmc_gen_info.h>
27 #include <hal_machperiph.h>
30 #include "appl_defs.h"
31 #include "appl_fpga.h"
33 int pxmc_ptofs_from_index(pxmc_state_t *mcs, unsigned long irc,
34 unsigned long index_irc, int diff2err);
36 #ifndef pxmc_fast_tick_time
37 #define pxmc_fast_tick_time() (LPC_TIM0->TC)
40 #define PXML_MAIN_CNT 8
42 #define PXMC_WITH_PT_ZIC 1
43 #define PXMC_PT_ZIC_MASK 0x8000
45 #define LPCPWM1_FREQ 20000
47 #define HAL_ERR_SENSITIVITY 20
48 #define HAL_ERR_MAX_COUNT 5
50 unsigned pxmc_rocon_pwm_magnitude = 2500;
52 long pxmc_rocon_irc_offset[PXML_MAIN_CNT];
53 unsigned pxmc_rocon_mark_filt[PXML_MAIN_CNT];
55 const uint8_t onesin10bits[1024]={
56 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
57 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
58 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
59 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
60 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
61 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
62 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
63 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
64 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
65 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
66 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
67 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
68 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
69 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
70 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
71 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,
72 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
73 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
74 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
75 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
76 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
77 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
78 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
79 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,
80 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
81 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
82 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
83 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,
84 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
85 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,
86 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,
87 5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10
91 pxmc_inp_rocon_inp(struct pxmc_state *mcs)
93 int chan=mcs->pxms_inp_info;
97 /* read position from hardware */
98 irc = fpga_irc[chan]->count;
99 irc += pxmc_rocon_irc_offset[chan];
100 pos = irc << PXMC_SUBDIV(mcs);
101 mcs->pxms_as = pos - mcs->pxms_ap;
104 /* Running of the motor commutator */
105 if (mcs->pxms_flg & PXMS_PTI_m)
106 pxmc_irc_16bit_commindx(mcs, irc);
112 pxmc_inp_rocon_is_mark(pxmc_state_t *mcs)
117 int chan=mcs->pxms_inp_info;
119 irc_state = *fpga_irc_state[chan];
121 mark = (irc_state ^ (mcs->pxms_cfg >> PXMS_CFG_HPS_b)) & 1;
123 filt = pxmc_rocon_mark_filt[chan];
124 filt = (filt << 1) | mark;
125 pxmc_rocon_mark_filt[chan] = filt;
127 return onesin10bits[filt & 0x03ff];
131 pxmc_inp_rocon_is_index_edge(pxmc_state_t *mcs)
135 int chan=mcs->pxms_inp_info;
137 irc_state = *fpga_irc_state[chan];
138 *fpga_irc_state[chan] = 1 << 2;
140 index = (irc_state >> 2) & 1;
146 pxmc_inp_rocon_adjust_to_irc_change(struct pxmc_state *mcs, long irc_diff)
148 long pos_diff = irc_diff << PXMC_SUBDIV(mcs);
150 mcs->pxms_ptofs += irc_diff;
152 mcs->pxms_ap += pos_diff;
153 mcs->pxms_rp += pos_diff;
158 pxmc_inp_rocon_irc_offset_from_index(struct pxmc_state *mcs)
160 int chan=mcs->pxms_inp_info;
164 irc_offset = -fpga_irc[chan]->count_index;
165 irc_diff = irc_offset - pxmc_rocon_irc_offset[chan];
166 pxmc_rocon_irc_offset[chan] = irc_offset;
167 return pxmc_inp_rocon_adjust_to_irc_change(mcs, irc_diff);
171 pxmc_inp_rocon_ap_zero(struct pxmc_state *mcs)
173 int chan=mcs->pxms_inp_info;
177 irc_offset = -fpga_irc[chan]->count;
178 irc_diff = irc_offset - pxmc_rocon_irc_offset[chan];
179 pxmc_rocon_irc_offset[chan] = irc_offset;
180 return pxmc_inp_rocon_adjust_to_irc_change(mcs, irc_diff);
184 pxmc_inp_rocon_ap2hw(struct pxmc_state *mcs)
186 int chan=mcs->pxms_inp_info;
190 irc = fpga_irc[chan]->count;
191 pos_diff = mcs->pxms_ap - (irc << PXMC_SUBDIV(mcs));
193 irc = pos_diff >> PXMC_SUBDIV(mcs);
195 /* Adjust phase table alignemt to modified IRC readout */
196 mcs->pxms_ptofs += irc - pxmc_rocon_irc_offset[chan];
198 pxmc_rocon_irc_offset[chan] = irc;
203 pxmc_inp_rocon_ptofs_from_index_poll(struct pxmc_state *mcs, int diff2err)
205 int chan=mcs->pxms_inp_info;
209 if (!(*fpga_irc_state[chan] & (1 << 2)))
212 irc = fpga_irc[chan]->count + pxmc_rocon_irc_offset[chan];
213 index_irc = fpga_irc[chan]->count_index + pxmc_rocon_irc_offset[chan];
215 return pxmc_ptofs_from_index(mcs, irc, index_irc, diff2err);
219 pxmc_rocon_bdc_hal_rd(pxmc_state_t *mcs)
224 /* return 3 bits corresponding to the HAL senzor input */
229 const unsigned char pxmc_lpc_bdc_hal_pos_table[8] =
241 const unsigned char pxmc_lpc_bdc_hal_pos_table[8] =
254 uint32_t pxmc_rocon_pwm_dummy_reg;
256 static inline volatile uint32_t *
257 pxmc_rocon_pwm_chan2reg(unsigned chan)
259 volatile uint32_t *pwm_reg;
262 return &pxmc_rocon_pwm_dummy_reg;
264 pwm_reg = fpga_lx_master_transmitter_base;
265 #if 0 /* FPGA design version 2 */
266 pwm_reg += 1 + (chan >> 8) + chan;
267 #else /* FPGA design version 3 */
274 * pxmc_rocon_pwm3ph_wr - Output of the 3-phase PWM to the hardware
275 * @mcs: Motion controller state information
277 /*static*/ inline void
278 pxmc_rocon_pwm3ph_wr(pxmc_state_t *mcs, short pwm1, short pwm2, short pwm3)
280 volatile uint32_t *pwm_reg_a, *pwm_reg_b, *pwm_reg_c;
281 int chan = mcs->pxms_out_info;
283 pwm_reg_c = pxmc_rocon_pwm_chan2reg(chan + 0);
284 pwm_reg_b = pxmc_rocon_pwm_chan2reg(chan + 1);
285 pwm_reg_a = pxmc_rocon_pwm_chan2reg(chan + 2);
293 pxmc_rocon_process_hal_error(struct pxmc_state *mcs)
295 if (mcs->pxms_halerc >= HAL_ERR_SENSITIVITY * HAL_ERR_MAX_COUNT)
297 pxmc_set_errno(mcs, PXMS_E_HAL);
302 mcs->pxms_halerc += HAL_ERR_SENSITIVITY;
306 * pxmc_rocon_pwm3ph_out - Phase output for brush-less 3-phase motor
307 * @mcs: Motion controller state information
310 pxmc_rocon_pwm3ph_out(pxmc_state_t *mcs)
312 typeof(mcs->pxms_ptvang) ptvang;
314 unsigned char hal_pos;
322 if (!(mcs->pxms_flg & PXMS_PTI_m) || !(mcs->pxms_flg & PXMS_PHA_m) ||
323 (mcs->pxms_flg & PXMS_PRA_m))
326 short ptirc = mcs->pxms_ptirc;
327 short divisor = mcs->pxms_ptper * 6;
330 pxmc_irc_16bit_commindx(mcs, mcs->pxms_rp >> PXMC_SUBDIV(mcs));
335 res = pxmc_inp_rocon_ptofs_from_index_poll(mcs, 0);
337 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
339 pxmc_set_flag(mcs, PXMS_PTI_b);
340 pxmc_set_flag(mcs, PXMS_PHA_b);
345 hal_pos = pxmc_lpc_bdc_hal_pos_table[pxmc_rocon_bdc_hal_rd(mcs)];
350 pxmc_rocon_process_hal_error(mcs);
354 if (mcs->pxms_halerc)
357 ptindx = (hal_pos * ptirc + divisor / 2) / divisor;
359 if (!(mcs->pxms_flg & PXMS_PTI_m) || (mcs->pxms_flg & PXMS_PRA_m))
361 if (((hal_pos != mcs->pxms_hal) && (mcs->pxms_hal != 0x40)) && 1)
363 short ptindx_prev = (mcs->pxms_hal * ptirc + divisor / 2) / divisor;;
365 if ((ptindx > ptindx_prev + ptirc / 2) ||
366 (ptindx_prev > ptindx + ptirc / 2))
368 ptindx = (ptindx_prev + ptindx - ptirc) / 2;
375 ptindx = (ptindx_prev + ptindx) / 2;
378 mcs->pxms_ptindx = ptindx;
380 mcs->pxms_ptofs = (mcs->pxms_ap >> PXMC_SUBDIV(mcs)) + mcs->pxms_ptshift - ptindx;
382 pxmc_set_flag(mcs, PXMS_PTI_b);
383 pxmc_clear_flag(mcs, PXMS_PRA_b);
385 /* if phase table position to mask is know do fine phase table alignment */
386 if (mcs->pxms_cfg & PXMS_CFG_I2PT_m) {
387 /*pxmc_inp_rocon_is_index_edge(mcs);*/
392 if (!(mcs->pxms_flg & PXMS_PTI_m))
393 mcs->pxms_ptindx = ptindx;
397 mcs->pxms_hal = hal_pos;
403 /*wind_current[0]=(ADC->ADDR0 & 0xFFF0)>>4;*/
404 /* FIXME - check winding current against limit */
405 /* pxmc_set_errno(mcs, PXMS_E_WINDCURRENT); */
409 ptvang = mcs->pxms_ptvang;
413 ene = mcs->pxms_flg & PXMS_BSY_m? mcs->pxms_me: 0;
417 indx = mcs->pxms_ptindx;
419 /* tuning of magnetic field/voltage advance angle */
420 indx += (mcs->pxms_s1 * mcs->pxms_as) >> (PXMC_SUBDIV(mcs) + 8);
425 /* Generating direction of stator mag. field for backward torque */
428 if ((indx -= ptvang) < 0)
429 indx += mcs->pxms_ptirc;
433 /* Generating direction of stator mag. field for forward torque */
434 if ((indx += ptvang) >= mcs->pxms_ptirc)
435 indx -= mcs->pxms_ptirc;
438 if (mcs->pxms_ptscale_mult)
439 indx = ((unsigned long)indx * mcs->pxms_ptscale_mult) >> mcs->pxms_ptscale_shift;
441 pwm1 = mcs->pxms_ptptr1[indx];
442 pwm2 = mcs->pxms_ptptr2[indx];
443 pwm3 = mcs->pxms_ptptr3[indx];
445 #ifdef PXMC_WITH_PT_ZIC
446 if (labs(mcs->pxms_as) < (10 << PXMC_SUBDIV(mcs)))
448 pwm1 &= ~PXMC_PT_ZIC_MASK;
449 pwm2 &= ~PXMC_PT_ZIC_MASK;
450 pwm3 &= ~PXMC_PT_ZIC_MASK;
452 #endif /*PXMC_WITH_PT_ZIC*/
454 /* Default phase-table amplitude is 0x7fff, ene max is 0x7fff */
455 /* Initialized CTM4 PWM period is 0x200 => divide by value about 2097024 */
457 unsigned long pwm_dc = pxmc_rocon_pwm_magnitude * (unsigned long)ene;
458 if (pwm1 & PXMC_PT_ZIC_MASK)
461 pwm1 = (((unsigned long long)pwm1 * pwm_dc) >> (15 + 15)) | 0x4000;
462 if (pwm2 & PXMC_PT_ZIC_MASK)
465 pwm2 = (((unsigned long long)pwm2 * pwm_dc) >> (15 + 15)) | 0x4000;
466 if (pwm3 & PXMC_PT_ZIC_MASK)
469 pwm3 = (((unsigned long long)pwm3 * pwm_dc) >> (15 + 15)) | 0x4000;
471 pxmc_rocon_pwm3ph_wr(mcs, pwm1, pwm2, pwm3);
475 pxmc_rocon_pwm3ph_wr(mcs, 0, 0, 0);
482 * pxmc_rocon_pwm2ph_wr - Output of the 2-phase stepper motor PWM to the hardware
483 * @mcs: Motion controller state information
485 /*static*/ inline void
486 pxmc_rocon_pwm2ph_wr(pxmc_state_t *mcs, short pwm1, short pwm2)
488 volatile uint32_t *pwm_reg_ap, *pwm_reg_an, *pwm_reg_bp, *pwm_reg_bn;
489 int chan = mcs->pxms_out_info;
491 pwm_reg_bn = pxmc_rocon_pwm_chan2reg(chan + 0);
492 pwm_reg_bp = pxmc_rocon_pwm_chan2reg(chan + 1);
493 pwm_reg_an = pxmc_rocon_pwm_chan2reg(chan + 2);
494 pwm_reg_ap = pxmc_rocon_pwm_chan2reg(chan + 3);
497 *pwm_reg_bp = pwm2 | 0x4000;
501 *pwm_reg_bn = -pwm2 | 0x4000;
505 *pwm_reg_ap = pwm1 | 0x4000;
509 *pwm_reg_an = -pwm1 | 0x4000;
514 * pxmc_rocon_pwm2ph_out - Phase output of the 2-phase stepper motor PWM
515 * @mcs: Motion controller state information
518 pxmc_rocon_pwm2ph_out(pxmc_state_t *mcs)
520 typeof(mcs->pxms_ptvang) ptvang;
528 if(!(mcs->pxms_flg&PXMS_PTI_m) || !(mcs->pxms_flg&PXMS_PHA_m) ||
529 (mcs->pxms_flg&PXMS_PRA_m)){
531 short ptirc=mcs->pxms_ptirc;
534 pxmc_irc_16bit_commindx(mcs, mcs->pxms_rp >> PXMC_SUBDIV(mcs));
539 res = pxmc_inp_rocon_ptofs_from_index_poll(mcs, 0);
541 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
543 pxmc_set_flag(mcs, PXMS_PTI_b);
544 pxmc_set_flag(mcs, PXMS_PHA_b);
549 ptindx = mcs->pxms_ptindx;
551 if(0 && (!(mcs->pxms_flg&PXMS_PTI_m) || (mcs->pxms_flg&PXMS_PRA_m))) {
553 mcs->pxms_ptindx = ptindx;
555 mcs->pxms_ptofs = (mcs->pxms_ap >> PXMC_SUBDIV(mcs)) + mcs->pxms_ptshift - ptindx;
557 pxmc_set_flag(mcs, PXMS_PTI_b);
558 pxmc_clear_flag(mcs, PXMS_PRA_b);
560 /* if phase table position to mask is know do fine phase table alignment */
561 //if(mcs->pxms_cfg & PXMS_CFG_I2PT_m)
562 // lpc_qei_setup_index_catch(&lpc_qei_state);
565 if(!(mcs->pxms_flg&PXMS_PTI_m))
566 mcs->pxms_ptindx = ptindx;
572 /*wind_current[0]=(ADC->ADDR0 & 0xFFF0)>>4;*/
573 /* FIXME - check winding current against limit */
574 /* pxmc_set_errno(mcs, PXMS_E_WINDCURRENT); */
578 ptvang = mcs->pxms_ptvang;
582 ene = mcs->pxms_flg & PXMS_BSY_m? mcs->pxms_me: 0;
586 indx = mcs->pxms_ptindx;
588 /* tuning of magnetic field/voltage advance angle */
589 indx += (mcs->pxms_s1 * mcs->pxms_as) >> (PXMC_SUBDIV(mcs) + 8);
592 /* Generating direction of stator mag. field for backward torque */
594 if ((indx -= ptvang)<0)
595 indx += mcs->pxms_ptirc;
597 /* Generating direction of stator mag. field for forward torque */
598 if ((indx += ptvang) >= mcs->pxms_ptirc)
599 indx -= mcs->pxms_ptirc;
602 if (mcs->pxms_ptscale_mult)
603 indx = ((unsigned long)indx * mcs->pxms_ptscale_mult) >> mcs->pxms_ptscale_shift;
605 pwm1 = mcs->pxms_ptptr1[indx];
606 pwm2 = mcs->pxms_ptptr2[indx];
608 /* Default phase-table amplitude is 0x7fff, ene max is 0x7fff */
609 /* Initialized PWM period is 0x200 => divide by value about 2097024 */
611 unsigned long pwm_dc = pxmc_rocon_pwm_magnitude * (unsigned long)ene;
612 pwm1 = ((unsigned long long)pwm1 * pwm_dc) >> (15+15);
613 pwm2 = ((unsigned long long)pwm2 * pwm_dc) >> (15+15);
615 pxmc_rocon_pwm2ph_wr(mcs, pwm1, pwm2);
617 /*pxmc_lpc_wind_current_over_cnt = 0;*/
618 pxmc_rocon_pwm2ph_wr(mcs, 0, 0);
625 * pxmc_rocon_pwm_dc_out - DC motor CW and CCW PWM output
626 * @mcs: Motion controller state information
629 pxmc_rocon_pwm_dc_out(pxmc_state_t *mcs)
631 volatile uint32_t *pwm_reg_a, *pwm_reg_b;
632 int chan = mcs->pxms_out_info;
633 int ene = mcs->pxms_ene;
635 pwm_reg_a = pxmc_rocon_pwm_chan2reg(chan + 0);
636 pwm_reg_b = pxmc_rocon_pwm_chan2reg(chan + 1);
642 ene = (ene * (pxmc_rocon_pwm_magnitude + 5)) >> 15;
644 *pwm_reg_b = ene | 0x4000;
648 ene = (ene * (pxmc_rocon_pwm_magnitude + 5)) >> 15;
650 *pwm_reg_a = ene | 0x4000;
656 /* PWM outputs placed on (PWM1), PWM2, PWM4, PWM6 */
658 pxmc_rocon_pwm_master_init(void)
663 *fpga_lx_master_reset = 1;
664 *fpga_lx_master_transmitter_reg = 0;
666 for (i = 0; i < 8 + 16; i ++)
667 fpga_lx_master_transmitter_base[i] = 0;
669 fpga_lx_master_transmitter_base[grp++] = 0x0808;
670 /*fpga_lx_master_transmitter_base[grp++] = 0x1008;*/
671 fpga_lx_master_transmitter_base[grp++] = 0x0000;
673 *fpga_lx_master_reset = 0;
678 int pxmc_ptofs_from_index(pxmc_state_t *mcs, unsigned long irc,
679 unsigned long index_irc, int diff2err)
684 ofs = ofsl = index_irc - mcs->pxms_ptmark;
688 diff = (unsigned short)ofs - (unsigned short)mcs->pxms_ptofs;
689 if (diff >= mcs->pxms_ptirc / 2)
690 diff -= mcs->pxms_ptirc;
691 if (diff <= -mcs->pxms_ptirc / 2)
692 diff += mcs->pxms_ptirc;
695 if(diff >= mcs->pxms_ptirc / 6) {
700 diff = (unsigned long)ofsl - irc;
701 ofs = ofsl - (diff / mcs->pxms_ptirc) * mcs->pxms_ptirc;
704 mcs->pxms_ptofs = ofs;
710 * pxmc_dummy_con - Dummy controller for synchronous BLDC/PMSM/steper drive
711 * @mcs: Motion controller state information
714 pxmc_dummy_con(pxmc_state_t *mcs)
719 int pxmc_rocon_hh_gd10(pxmc_state_t *mcs);
720 int pxmc_rocon_hh_gd20(pxmc_state_t *mcs);
721 int pxmc_rocon_hh_gd30(pxmc_state_t *mcs);
722 int pxmc_rocon_hh_gd40(pxmc_state_t *mcs);
723 int pxmc_rocon_hh_gd50(pxmc_state_t *mcs);
724 int pxmc_rocon_hh_gd90(pxmc_state_t *mcs);
726 /* initialize for hard home */
728 pxmc_rocon_hh_gi(pxmc_state_t *mcs)
730 pxmc_set_flag(mcs,PXMS_BSY_b);
731 #if 0 /* config and speed already set in pxmc_hh */
733 spd >>= mcs->pxms_cfg & PXMS_CFG_HSPD_m;
735 if(mcs->pxms_cfg & PXMS_CFG_HDIR_m)
737 mcs->pxms_gen_hsp = spd;
740 mcs->pxms_gen_htim = 16;
741 mcs->pxms_do_gen = pxmc_rocon_hh_gd10;
742 return pxmc_rocon_hh_gd10(mcs);
745 /* fill initial mark filter and then decide */
747 pxmc_rocon_hh_gd10(pxmc_state_t *mcs)
751 if(mcs->pxms_flg & PXMS_ERR_m)
752 return pxmc_spdnext_gend(mcs);
754 pxmc_spd_gacc(&(mcs->pxms_rs), 0, mcs->pxms_ma);
755 mcs->pxms_rp += mcs->pxms_rs;
757 mark = pxmc_inp_rocon_is_mark(mcs);
759 if (mcs->pxms_gen_htim) {
760 mcs->pxms_gen_htim--;
764 if (!(mcs->pxms_cfg & PXMS_CFG_HLS_m)) {
765 /* limit switch is not used */
766 pxmc_inp_rocon_is_index_edge(mcs);
767 mcs->pxms_do_gen = pxmc_rocon_hh_gd50;
772 /* go out from switch */
773 mcs->pxms_do_gen = pxmc_rocon_hh_gd20;
775 /* switch is off -> look for it */
776 mcs->pxms_do_gen = pxmc_rocon_hh_gd30;
781 /* go out from switch */
783 pxmc_rocon_hh_gd20(pxmc_state_t *mcs)
787 if(mcs->pxms_flg & PXMS_ERR_m)
788 return pxmc_spdnext_gend(mcs);
790 mark = pxmc_inp_rocon_is_mark(mcs);
793 /* switch is off -> look for it again */
794 mcs->pxms_do_gen = pxmc_rocon_hh_gd30;
797 pxmc_spd_gacc(&(mcs->pxms_rs), -mcs->pxms_gen_hsp, mcs->pxms_ma);
798 mcs->pxms_rp += mcs->pxms_rs;
803 /* switch is off -> look for it */
805 pxmc_rocon_hh_gd30(pxmc_state_t *mcs)
810 if (mcs->pxms_flg & PXMS_ERR_m)
811 return pxmc_spdnext_gend(mcs);
813 pxmc_spd_gacc(&(mcs->pxms_rs), mcs->pxms_gen_hsp, mcs->pxms_ma);
814 mcs->pxms_rp += mcs->pxms_rs;
816 mark = pxmc_inp_rocon_is_mark(mcs);
819 spd = mcs->pxms_gen_hsp >> 2; /* slow down */
822 mcs->pxms_gen_hsp = spd;
823 mcs->pxms_do_gen = pxmc_rocon_hh_gd40;
829 /* switch is on -> find edge */
831 pxmc_rocon_hh_gd40(pxmc_state_t *mcs)
835 if (mcs->pxms_flg & PXMS_ERR_m)
836 return pxmc_spdnext_gend(mcs);
838 mark = pxmc_inp_rocon_is_mark(mcs);
841 if (mcs->pxms_cfg & PXMS_CFG_HRI_m) {
842 pxmc_inp_rocon_is_index_edge(mcs);
843 mcs->pxms_do_gen = pxmc_rocon_hh_gd50;
845 pxmc_inp_rocon_ap_zero(mcs);
846 mcs->pxms_do_gen = pxmc_stop_gi;
850 pxmc_spd_gacc(&(mcs->pxms_rs), -mcs->pxms_gen_hsp, mcs->pxms_ma);
851 mcs->pxms_rp += mcs->pxms_rs;
856 /* calibrate on revolution index */
858 pxmc_rocon_hh_gd50(pxmc_state_t *mcs)
860 if (mcs->pxms_flg & PXMS_ERR_m)
861 return pxmc_spdnext_gend(mcs);
863 pxmc_spd_gacc(&(mcs->pxms_rs), mcs->pxms_gen_hsp, mcs->pxms_ma);
864 mcs->pxms_rp += mcs->pxms_rs;
866 if (pxmc_inp_rocon_is_index_edge(mcs)){
867 pxmc_inp_rocon_irc_offset_from_index(mcs);
868 mcs->pxms_do_gen = pxmc_stop_gi;
874 pxmc_call_t *pxmc_get_hh_gi_4axis(pxmc_state_t *mcs)
876 return pxmc_rocon_hh_gi;
886 pxmc_pid_con /*pxmc_dummy_con*/,
888 pxmc_rocon_pwm_dc_out /*pxmc_rocon_pwm3ph_out*/,
892 pxmc_inp_rocon_ap2hw,
893 pxms_ap: 0, pxms_as: 0,
894 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
895 pxms_md: 800 << 8, pxms_ms: 1000, pxms_ma: 10,
898 pxms_ene: 0, pxms_erc: 0,
899 pxms_p: 80, pxms_i: 30, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
900 pxms_me: 0x7e00/*0x7fff*/,
902 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m | PXMS_CFG_HRI_m | PXMS_CFG_I2PT_m * 0 |
903 PXMS_CFG_HDIR_m | 0x2,
908 /*pxms_ptamp: 0x7fff,*/
922 pxmc_rocon_pwm_dc_out,
926 pxmc_inp_rocon_ap2hw,
927 pxms_ap: 0, pxms_as: 0,
928 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
929 pxms_md: 800 << 8, pxms_ms: 1000, pxms_ma: 10,
932 pxms_ene: 0, pxms_erc: 0,
933 pxms_p: 80, pxms_i: 30, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
934 pxms_me: 0x7e00/*0x7fff*/,
936 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m * 0 | PXMS_CFG_HRI_m | PXMS_CFG_I2PT_m * 0 |
937 PXMS_CFG_HDIR_m | 0x2,
941 /*pxms_ptamp: 0x7fff,*/
955 pxmc_rocon_pwm_dc_out,
959 pxmc_inp_rocon_ap2hw,
960 pxms_ap: 0, pxms_as: 0,
961 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
962 pxms_md: 800 << 8, pxms_ms: 1000, pxms_ma: 10,
965 pxms_ene: 0, pxms_erc: 0,
966 pxms_p: 80, pxms_i: 30, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
967 pxms_me: 0x7e00/*0x7fff*/,
969 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m * 0 | PXMS_CFG_I2PT_m * 0 | PXMS_CFG_HRI_m |
974 /*pxms_ptamp: 0x7fff,*/
988 pxmc_rocon_pwm_dc_out,
992 pxmc_inp_rocon_ap2hw,
993 pxms_ap: 0, pxms_as: 0,
994 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
995 pxms_md: 800 << 8, pxms_ms: 1000, pxms_ma: 10,
998 pxms_ene: 0, pxms_erc: 0,
999 pxms_p: 80, pxms_i: 30, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1000 pxms_me: 0x7e00/*0x7fff*/,
1002 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m * 0 | PXMS_CFG_I2PT_m * 0 | PXMS_CFG_HRI_m |
1003 PXMS_CFG_HDIR_m | 0x2,
1007 /*pxms_ptamp: 0x7fff,*/
1021 pxmc_rocon_pwm_dc_out,
1025 pxmc_inp_rocon_ap2hw,
1026 pxms_ap: 0, pxms_as: 0,
1027 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1028 pxms_md: 800 << 8, pxms_ms: 1000, pxms_ma: 10,
1031 pxms_ene: 0, pxms_erc: 0,
1032 pxms_p: 80, pxms_i: 30, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1033 pxms_me: 0x7e00/*0x7fff*/,
1035 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_I2PT_m * 0 |
1040 /*pxms_ptamp: 0x7fff,*/
1054 pxmc_rocon_pwm_dc_out,
1058 pxmc_inp_rocon_ap2hw,
1059 pxms_ap: 0, pxms_as: 0,
1060 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1061 pxms_md: 800 << 8, pxms_ms: 1000, pxms_ma: 10,
1064 pxms_ene: 0, pxms_erc: 0,
1065 pxms_p: 80, pxms_i: 30, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1066 pxms_me: 0x7e00/*0x7fff*/,
1068 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_I2PT_m * 0 |
1073 /*pxms_ptamp: 0x7fff,*/
1087 pxmc_rocon_pwm_dc_out,
1091 pxmc_inp_rocon_ap2hw,
1092 pxms_ap: 0, pxms_as: 0,
1093 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1094 pxms_md: 800 << 8, pxms_ms: 1000, pxms_ma: 10,
1097 pxms_ene: 0, pxms_erc: 0,
1098 pxms_p: 80, pxms_i: 30, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1099 pxms_me: 0x7e00/*0x7fff*/,
1101 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_I2PT_m * 0 |
1106 /*pxms_ptamp: 0x7fff,*/
1120 pxmc_rocon_pwm_dc_out,
1124 pxmc_inp_rocon_ap2hw,
1125 pxms_ap: 0, pxms_as: 0,
1126 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1127 pxms_md: 800 << 8, pxms_ms: 1000, pxms_ma: 10,
1130 pxms_ene: 0, pxms_erc: 0,
1131 pxms_p: 80, pxms_i: 30, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1132 pxms_me: 0x7e00/*0x7fff*/,
1134 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_I2PT_m * 0 |
1139 /*pxms_ptamp: 0x7fff,*/
1145 pxmc_state_t *pxmc_main_arr[PXML_MAIN_CNT] =
1146 {&mcs0, &mcs1, &mcs2, &mcs3, &mcs4, &mcs5, &mcs6, &mcs7};
1149 pxmc_state_list_t pxmc_main_list =
1156 void pxmc_lpc_qei_callback_index(struct lpc_qei_state_t *qst, void *context)
1158 pxmc_state_t *mcs = (pxmc_state_t *)context;
1161 irc = qst->index_pos;
1163 if ((mcs->pxms_cfg & PXMS_CFG_I2PT_m) && (mcs->pxms_flg & PXMS_PTI_m))
1166 ofs = irc - mcs->pxms_ptmark;
1167 diff = ofs - mcs->pxms_ptofs;
1169 if (diff >= mcs->pxms_ptirc / 2)
1170 diff -= mcs->pxms_ptirc;
1172 if (diff <= -mcs->pxms_ptirc / 2)
1173 diff += mcs->pxms_ptirc;
1178 if (diff >= mcs->pxms_ptirc / 6)
1180 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
1184 mcs->pxms_ptofs = ofs;
1185 pxmc_set_flag(mcs, PXMS_PHA_b);
1189 ofs=irc-mcs->pxms_ptofs;
1190 if((unsigned short)ofs>=(unsigned short)mcs->pxms_ptirc) {
1192 ofs-=mcs->pxms_ptirc;
1194 ofs+=mcs->pxms_ptirc;
1197 mcs->pxms_ptmark=ofs;
1200 /*lpc_qei_set_cmpos(qst, 0, qst->index_pos-4000);*/
1203 int pxmc_lpc_pthalalign_callback(pxmc_state_t *mcs)
1207 lpc_qei_state_t *qst = &lpc_qei_state;
1208 int irc = lpc_qei_get_pos(qst);
1211 if (!qst->index_occ)
1214 idx_rel = qst->index_pos - irc;
1215 idx_rel %= mcs->pxms_ptirc;
1218 idx_rel += mcs->pxms_ptirc;
1220 ptofs = irc - mcs->pxms_ptofs;
1221 ptmark = ptofs + idx_rel;
1223 if ((unsigned short)ptmark >= mcs->pxms_ptirc)
1226 ptmark -= mcs->pxms_ptirc;
1228 ptmark += mcs->pxms_ptirc;
1231 if ((unsigned short)ptmark < mcs->pxms_ptirc)
1233 mcs->pxms_ptmark = ptmark;
1239 int pxmc_lpc_pthalalign(pxmc_state_t *mcs, int periods)
1244 pxmc_call_t *fin_fnc = pxmc_lpc_pthalalign_callback;
1245 lpc_qei_state_t *qst = &lpc_qei_state;
1247 mcs->pxms_cfg &= ~PXMS_CFG_I2PT_m;
1248 lpc_qei_setup_index_catch(qst);
1250 r2acq = ((long)mcs->pxms_ptirc << PXMC_SUBDIV(mcs)) * periods;
1251 spd = 1 << PXMC_SUBDIV(mcs);
1253 res = pxmc_pthalalign(mcs, r2acq, spd, fin_fnc);
1258 int pxmc_lpc_pthalalign_run(void)
1260 return pxmc_lpc_pthalalign(pxmc_main_list.pxml_arr[0], 20);
1263 static inline void pxmc_sfi_input(void)
1267 pxmc_for_each_mcs(var, mcs)
1269 /* PXMS_ENI_m - check if input (IRC) update is enabled */
1270 if (mcs->pxms_flg & PXMS_ENI_m)
1272 pxmc_call(mcs, mcs->pxms_do_inp);
1277 static inline void pxmc_sfi_controller_and_output(void)
1281 pxmc_for_each_mcs(var, mcs)
1283 /* PXMS_ENR_m - check if controller is enabled */
1284 if (mcs->pxms_flg & PXMS_ENR_m || mcs->pxms_flg & PXMS_ENO_m)
1287 /* If output only is enabled, we skip the controller */
1288 if (mcs->pxms_flg & PXMS_ENR_m)
1291 pxmc_call(mcs, mcs->pxms_do_con);
1293 /* PXMS_ERR_m - if axis in error state */
1294 if (mcs->pxms_flg & PXMS_ERR_m)
1298 /* for bushless motors, it is necessary to call do_out
1299 even if the controller is not enabled and PWM should be provided. */
1300 pxmc_call(mcs, mcs->pxms_do_out);
1305 static inline void pxmc_sfi_generator(void)
1309 pxmc_for_each_mcs(var, mcs)
1311 /* PXMS_ENG_m - check if requested value (position) generator is enabled */
1312 if (mcs->pxms_flg & PXMS_ENG_m)
1314 pxmc_call(mcs, mcs->pxms_do_gen);
1319 static inline void pxmc_sfi_dbg(void)
1323 pxmc_for_each_mcs(var, mcs)
1325 if (mcs->pxms_flg & PXMS_DBG_m)
1327 pxmc_call(mcs, mcs->pxms_do_deb);
1332 int pxmc_rocon_pthalalign_callback(pxmc_state_t *mcs)
1336 int inp_chan = mcs->pxms_inp_info;
1338 long irc = fpga_irc[inp_chan]->count;
1340 if (!pxmc_inp_rocon_is_index_edge(mcs))
1343 idx_rel = fpga_irc[inp_chan]->count_index - irc;
1344 idx_rel %= mcs->pxms_ptirc;
1346 idx_rel += mcs->pxms_ptirc;
1348 ptofs = irc-mcs->pxms_ptofs;
1349 ptmark = ptofs+idx_rel;
1351 if((unsigned short)ptmark >= mcs->pxms_ptirc) {
1353 ptmark -= mcs->pxms_ptirc;
1355 ptmark += mcs->pxms_ptirc;
1358 if((unsigned short)ptmark < mcs->pxms_ptirc) {
1359 mcs->pxms_ptmark = ptmark;
1364 int pxmc_rocon_pthalalign(pxmc_state_t *mcs, int periods)
1369 pxmc_call_t *fin_fnc = pxmc_rocon_pthalalign_callback;
1371 mcs->pxms_cfg&=~PXMS_CFG_I2PT_m;
1373 r2acq=((long)mcs->pxms_ptirc<<PXMC_SUBDIV(mcs))*periods;
1374 spd=1<<PXMC_SUBDIV(mcs);
1376 /* clear bit indicating previous index */
1377 pxmc_inp_rocon_is_index_edge(mcs);
1379 res=pxmc_pthalalign(mcs, r2acq, spd, fin_fnc);
1384 int pxmc_axis_rdmode(pxmc_state_t *mcs)
1386 if (mcs->pxms_do_out == pxmc_rocon_pwm2ph_out)
1387 return PXMC_AXIS_MODE_STEPPER_WITH_IRC;
1388 if (mcs->pxms_do_out == pxmc_rocon_pwm_dc_out)
1389 return PXMC_AXIS_MODE_DC;
1390 if (mcs->pxms_do_out == pxmc_rocon_pwm3ph_out)
1391 return PXMC_AXIS_MODE_BLDC;
1397 pxmc_axis_pt4mode(pxmc_state_t *mcs, int mode)
1399 static const typeof(*mcs->pxms_ptptr1) dummy0 = 0;
1402 if (mode == PXMC_AXIS_MODE_NOCHANGE)
1403 mode = pxmc_axis_rdmode(mcs);
1408 /*case PXMC_AXIS_MODE_STEPPER:*/
1409 case PXMC_AXIS_MODE_STEPPER_WITH_IRC:
1410 res = pxmc_ptable_set_profile(mcs, &pxmc_ptprofile_sin, 0, 0);
1412 /*case PXMC_AXIS_MODE_STEPPER_WITH_PWM:*/
1413 case PXMC_AXIS_MODE_DC:
1414 /*profive some sane dummy values*/
1415 mcs->pxms_ptptr1 = (typeof(mcs->pxms_ptptr1))&dummy0;
1416 mcs->pxms_ptptr2 = (typeof(mcs->pxms_ptptr1))&dummy0;
1417 mcs->pxms_ptptr3 = (typeof(mcs->pxms_ptptr1))&dummy0;
1419 mcs->pxms_ptscale_mult=1;
1420 mcs->pxms_ptscale_shift=15;
1422 case PXMC_AXIS_MODE_BLDC:
1423 /* res = pxmc_init_ptable(mcs, PXMC_PTPROF_SIN3FUP); */
1424 #ifndef PXMC_WITH_PT_ZIC
1425 res = pxmc_ptable_set_profile(mcs, &pxmc_ptprofile_sin3phup, 0, 0);
1426 #else /*PXMC_WITH_PT_ZIC*/
1427 res = pxmc_ptable_set_profile(mcs, &pxmc_ptprofile_sin3phup_zic, 0, 0);
1428 #endif /*PXMC_WITH_PT_ZIC*/
1434 mcs->pxms_ptvang = pxmc_ptvang_deg2irc(mcs, 90);
1440 * pxmc_axis_mode - Sets axis mode.[extern API]
1441 * @mcs: Motion controller state information
1442 * @mode: 0 .. previous mode, 1 .. stepper motor mode,
1443 * 2 .. stepper motor with IRC feedback and PWM ,
1444 * 3 .. stepper motor with PWM control
1445 * 4 .. DC motor with IRC feedback and PWM
1449 pxmc_axis_mode(pxmc_state_t *mcs, int mode)
1453 pxmc_set_const_out(mcs, 0);
1454 pxmc_clear_flag(mcs, PXMS_ENI_b);
1455 pxmc_clear_flags(mcs,PXMS_ENO_m);
1456 /* Clear possible stall index flags from hardware */
1457 pxmc_inp_rocon_is_index_edge(mcs);
1458 pxmc_clear_flag(mcs, PXMS_PHA_b);
1459 pxmc_clear_flag(mcs, PXMS_PTI_b);
1462 if (mode == PXMC_AXIS_MODE_NOCHANGE)
1463 mode = pxmc_axis_rdmode(mcs);
1467 mode = PXMC_AXIS_MODE_DC;
1469 res = pxmc_axis_pt4mode(mcs, mode);
1474 /*case PXMC_AXIS_MODE_STEPPER:*/
1475 case PXMC_AXIS_MODE_STEPPER_WITH_IRC:
1476 mcs->pxms_do_out = pxmc_rocon_pwm2ph_out;
1478 /*case PXMC_AXIS_MODE_STEPPER_WITH_PWM:*/
1479 case PXMC_AXIS_MODE_DC:
1480 mcs->pxms_do_out = pxmc_rocon_pwm_dc_out;
1482 case PXMC_AXIS_MODE_BLDC:
1483 mcs->pxms_do_out = pxmc_rocon_pwm3ph_out;
1489 /* Clear possible stall index flags from hardware */
1490 pxmc_inp_rocon_is_index_edge(mcs);
1491 /* Request new phases alignment for changed parameters */
1492 pxmc_clear_flag(mcs, PXMS_PHA_b);
1493 pxmc_clear_flag(mcs, PXMS_PTI_b);
1494 pxmc_set_flag(mcs, PXMS_ENI_b);
1498 void pxmc_sfi_isr(void)
1500 unsigned long spent = pxmc_fast_tick_time();
1503 pxmc_sfi_controller_and_output();
1504 pxmc_sfi_generator();
1506 /* Kick LX Master watchdog */
1507 if (pxmc_main_list.pxml_cnt != 0)
1508 *fpga_lx_master_transmitter_wdog = 1;
1510 spent = pxmc_fast_tick_time() - spent;
1512 if(spent > pxmc_sfi_spent_time_max)
1513 pxmc_sfi_spent_time_max = spent;
1517 int pxmc_clear_power_stop(void)
1522 int pxmc_process_state_check(unsigned long *pbusy_bits,
1523 unsigned long *perror_bits)
1526 unsigned short chan;
1527 unsigned long busy_bits = 0;
1528 unsigned long error_bits = 0;
1531 pxmc_for_each_mcs(chan, mcs) {
1533 flg |= mcs->pxms_flg;
1534 if (mcs->pxms_flg & PXMS_BSY_m)
1535 busy_bits |= 1 << chan;
1536 if (mcs->pxms_flg & PXMS_ERR_m)
1537 error_bits |= 1 << chan;
1540 if (appl_errstop_mode) {
1541 if((flg & PXMS_ENG_m) && (flg & PXMS_ERR_m)) {
1542 pxmc_for_each_mcs(chan, mcs) {
1543 if(mcs&&(mcs->pxms_flg & PXMS_ENG_m)) {
1550 if (pbusy_bits != NULL)
1551 *pbusy_bits = busy_bits;
1552 if (error_bits != NULL)
1553 *perror_bits = error_bits;
1563 if (!pxmc_main_list.pxml_cnt)
1566 pxmc_for_each_mcs(var, mcs)
1568 pxmc_set_const_out(mcs,0);
1571 pxmc_main_list.pxml_cnt = 0;
1577 int pxmc_initialize(void)
1582 pxmc_state_t *mcs = &mcs0;
1583 lpc_qei_state_t *qst = &lpc_qei_state;
1585 *fpga_irc_reset = 1;
1587 for (i = 0; i < 8; i++) {
1588 fpga_irc[i]->count = 0;
1589 *fpga_irc_state[i] = 1 << 2;
1592 /* Initialize QEI module for IRC counting */
1593 pxmc_inp_lpc_qei_init(mcs->pxms_inp_info);
1595 /* Initialize QEI events processing */
1596 if (lpc_qei_setup_irq(qst) < 0)
1599 *fpga_irc_reset = 0;
1601 //res = pxmc_axis_pt4mode(mcs, PXMC_AXIS_MODE_BLDC);
1603 /*pxmc_ctm4pwm3f_wr(mcs, 0, 0, 0);*/
1604 //pxmc_rocon_pwm3ph_wr(mcs, 0, 0, 0);
1606 pxmc_rocon_pwm_master_init();
1608 pxmc_main_list.pxml_cnt = 0;
1609 pxmc_dbg_hist = NULL;
1611 pxmc_main_list.pxml_cnt = PXML_MAIN_CNT;