1 /*******************************************************************
2 Motion and Robotic System (MARS) aplication components.
4 appl_pxmc.c - position controller RoCoN hardware support
6 Copyright (C) 2001-2013 by Pavel Pisa - originator
8 (C) 2001-2013 by PiKRON Ltd. - originator
11 This file can be used and copied according to next
13 - GPL - GNU Public License
14 - other license provided by project originators
16 *******************************************************************/
19 #include <system_def.h>
21 #include <pxmc_lpc_qei.h>
22 #include <pxmc_internal.h>
23 #include <pxmc_inp_common.h>
24 #include <pxmc_gen_info.h>
26 #include <hal_machperiph.h>
32 #include "appl_defs.h"
33 #include "appl_fpga.h"
34 #include "appl_pxmc.h"
35 #include "pxmcc_types.h"
36 #include "pxmcc_interface.h"
38 #define PXMC_AXIS_MODE_BLDC_PXMCC (PXMC_AXIS_MODE_BLDC + 1)
39 #define PXMC_AXIS_MODE_STEPPER_WITH_IRC_PXMCC (PXMC_AXIS_MODE_BLDC + 2)
40 #define PXMC_AXIS_MODE_STEPPER_PXMCC (PXMC_AXIS_MODE_BLDC + 3)
42 int pxmc_ptofs_from_index(pxmc_state_t *mcs, unsigned long irc,
43 unsigned long index_irc, int diff2err);
45 #ifndef pxmc_fast_tick_time
46 #define pxmc_fast_tick_time() (LPC_TIM0->TC)
49 #define PXML_MAIN_CNT 8
51 #define PXMC_WITH_PT_ZIC 1
52 #define PXMC_PT_ZIC_MASK 0x8000
54 #define LPCPWM1_FREQ 20000
56 #define HAL_ERR_SENSITIVITY 20
57 #define HAL_ERR_MAX_COUNT 5
59 #define LXPWR_WITH_SIROLADC 1
61 #define LX_MASTER_DATA_OFFS 8
63 #define PXMC_LXPWR_PWM_CYCLE 2500
65 unsigned pxmc_rocon_pwm_magnitude = PXMC_LXPWR_PWM_CYCLE;
67 long pxmc_rocon_irc_offset[PXML_MAIN_CNT];
68 unsigned pxmc_rocon_mark_filt[PXML_MAIN_CNT];
71 pxmc_rocon_state_t *pxmc_state2rocon_state(pxmc_state_t *mcs)
73 pxmc_rocon_state_t *mcsrc;
75 mcsrc = UL_CONTAINEROF(mcs, pxmc_rocon_state_t, base);
76 #else /*UL_CONTAINEROF*/
77 mcsrc = (pxmc_rocon_state_t*)((char*)mcs - __builtin_offsetof(pxmc_rocon_state_t, base));
78 #endif /*UL_CONTAINEROF*/
82 const uint8_t onesin10bits[1024]={
83 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,
84 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,
85 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,
86 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,
87 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,
88 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,
89 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,
90 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,
91 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,
92 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,
93 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,
94 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,
95 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,
96 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,
97 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,
98 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,
99 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,
100 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,
101 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,
102 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,
103 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,
104 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,
105 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,
106 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,
107 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,
108 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,
109 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,
110 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,
111 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,
112 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,
113 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,
114 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
118 pxmc_inp_rocon_inp(struct pxmc_state *mcs)
120 int chan=mcs->pxms_inp_info;
124 /* read position from hardware */
125 irc = fpga_irc[chan]->count;
126 irc += pxmc_rocon_irc_offset[chan];
127 pos = irc << PXMC_SUBDIV(mcs);
128 mcs->pxms_as = pos - mcs->pxms_ap;
131 /* Running of the motor commutator */
132 if (mcs->pxms_flg & PXMS_PTI_m)
133 pxmc_irc_16bit_commindx(mcs, irc);
139 pxmc_inp_rocon_is_mark(pxmc_state_t *mcs)
144 int chan=mcs->pxms_inp_info;
146 irc_state = *fpga_irc_state[chan];
148 mark = ((irc_state >> (ffs(FPGA_IRC_STATE_MARK_MASK) - 1)) ^
149 (mcs->pxms_cfg >> PXMS_CFG_HPS_b)) & 1;
151 filt = pxmc_rocon_mark_filt[chan];
152 filt = (filt << 1) | mark;
153 pxmc_rocon_mark_filt[chan] = filt;
155 return onesin10bits[filt & 0x03ff];
159 pxmc_inp_rocon_is_index_edge(pxmc_state_t *mcs)
163 int chan=mcs->pxms_inp_info;
165 irc_state = *fpga_irc_state[chan];
166 *fpga_irc_state[chan] = FPGA_IRC_STATE_INDEX_EVENT_MASK;
168 index = (irc_state >> (ffs(FPGA_IRC_STATE_INDEX_EVENT_MASK) - 1)) & 1;
174 pxmc_inp_rocon_adjust_to_irc_change(struct pxmc_state *mcs, long irc_diff)
176 long pos_diff = irc_diff << PXMC_SUBDIV(mcs);
178 mcs->pxms_ptofs += irc_diff;
180 mcs->pxms_ap += pos_diff;
181 mcs->pxms_rp += pos_diff;
186 pxmc_inp_rocon_irc_offset_from_index(struct pxmc_state *mcs)
188 int chan=mcs->pxms_inp_info;
192 irc_offset = -fpga_irc[chan]->count_index;
193 irc_diff = irc_offset - pxmc_rocon_irc_offset[chan];
194 pxmc_rocon_irc_offset[chan] = irc_offset;
195 return pxmc_inp_rocon_adjust_to_irc_change(mcs, irc_diff);
199 pxmc_inp_rocon_ap_zero(struct pxmc_state *mcs)
201 int chan=mcs->pxms_inp_info;
205 irc_offset = -fpga_irc[chan]->count;
206 irc_diff = irc_offset - pxmc_rocon_irc_offset[chan];
207 pxmc_rocon_irc_offset[chan] = irc_offset;
208 return pxmc_inp_rocon_adjust_to_irc_change(mcs, irc_diff);
212 pxmc_inp_rocon_ap2hw(struct pxmc_state *mcs)
214 int chan=mcs->pxms_inp_info;
218 irc = fpga_irc[chan]->count;
219 pos_diff = mcs->pxms_ap - (irc << PXMC_SUBDIV(mcs));
221 irc = pos_diff >> PXMC_SUBDIV(mcs);
223 /* Adjust phase table alignemt to modified IRC readout */
224 mcs->pxms_ptofs += irc - pxmc_rocon_irc_offset[chan];
226 pxmc_rocon_irc_offset[chan] = irc;
231 pxmc_inp_rocon_ptofs_from_index_poll(struct pxmc_state *mcs, int diff2err)
233 int chan=mcs->pxms_inp_info;
237 if (!(*fpga_irc_state[chan] & FPGA_IRC_STATE_INDEX_EVENT_MASK))
240 irc = fpga_irc[chan]->count + pxmc_rocon_irc_offset[chan];
241 index_irc = fpga_irc[chan]->count_index + pxmc_rocon_irc_offset[chan];
243 return pxmc_ptofs_from_index(mcs, irc, index_irc, diff2err);
246 uint32_t pxmc_rocon_receiver_dummy_reg;
248 static inline volatile uint32_t *
249 pxmc_rocon_receiver_chan2reg(unsigned chan)
251 volatile uint32_t *rec_reg;
254 return &pxmc_rocon_receiver_dummy_reg;
256 rec_reg = fpga_lx_master_receiver_base;
258 #ifdef LXPWR_WITH_SIROLADC
259 rec_reg += LX_MASTER_DATA_OFFS + 1 + (chan >> 3) * 3 + chan * 2;
260 #else /*LXPWR_WITH_SIROLADC*/
261 rec_reg += LX_MASTER_DATA_OFFS + chan;
262 #endif /*LXPWR_WITH_SIROLADC*/
268 pxmc_rocon_bldc_hal_rd(pxmc_state_t *mcs)
271 volatile uint32_t *rec_reg_a, *rec_reg_b, *rec_reg_c;
272 int chan = mcs->pxms_out_info;
275 #ifdef LXPWR_WITH_SIROLADC
277 #else /*LXPWR_WITH_SIROLADC*/
279 #endif /*LXPWR_WITH_SIROLADC*/
281 rec_reg_a = pxmc_rocon_receiver_chan2reg(chan + 0);
282 rec_reg_b = pxmc_rocon_receiver_chan2reg(chan + 1);
283 rec_reg_c = pxmc_rocon_receiver_chan2reg(chan + 2);
285 h = (rec_reg_a[hal_offs] >> 14) & 1;
286 h |= (rec_reg_b[hal_offs] >> 13) & 2;
287 h |= (rec_reg_c[hal_offs] >> 12) & 4;
289 /* return 3 bits corresponding to the HAL senzor input */
294 const unsigned char pxmc_lpc_bdc_hal_pos_table[8] =
306 const unsigned char pxmc_lpc_bdc_hal_pos_table[8] =
319 uint32_t pxmc_rocon_pwm_dummy_reg;
321 static inline volatile uint32_t *
322 pxmc_rocon_pwm_chan2reg(unsigned chan)
324 volatile uint32_t *pwm_reg;
327 return &pxmc_rocon_pwm_dummy_reg;
329 pwm_reg = fpga_lx_master_transmitter_base;
331 #ifdef LXPWR_WITH_SIROLADC
332 pwm_reg += LX_MASTER_DATA_OFFS + 1 + (chan >> 3) + chan;
333 #else /*LXPWR_WITH_SIROLADC*/
334 pwm_reg += LX_MASTER_DATA_OFFS + chan;
335 #endif /*LXPWR_WITH_SIROLADC*/
341 * pxmc_rocon_pwm3ph_wr - Output of the 3-phase PWM to the hardware
342 * @mcs: Motion controller state information
344 /*static*/ inline void
345 pxmc_rocon_pwm3ph_wr(pxmc_state_t *mcs, short pwm1, short pwm2, short pwm3)
347 volatile uint32_t *pwm_reg_a, *pwm_reg_b, *pwm_reg_c;
348 int chan = mcs->pxms_out_info;
350 pwm_reg_c = pxmc_rocon_pwm_chan2reg(chan + 0);
351 pwm_reg_b = pxmc_rocon_pwm_chan2reg(chan + 1);
352 pwm_reg_a = pxmc_rocon_pwm_chan2reg(chan + 2);
360 pxmc_rocon_process_hal_error(struct pxmc_state *mcs)
362 if (mcs->pxms_halerc >= HAL_ERR_SENSITIVITY * HAL_ERR_MAX_COUNT)
364 pxmc_set_errno(mcs, PXMS_E_HAL);
369 mcs->pxms_halerc += HAL_ERR_SENSITIVITY;
373 * pxmc_rocon_pwm3ph_out - Phase output for brush-less 3-phase motor
374 * @mcs: Motion controller state information
377 pxmc_rocon_pwm3ph_out(pxmc_state_t *mcs)
379 typeof(mcs->pxms_ptvang) ptvang;
381 unsigned char hal_pos;
389 if (!(mcs->pxms_flg & PXMS_PTI_m) || !(mcs->pxms_flg & PXMS_PHA_m) ||
390 (mcs->pxms_flg & PXMS_PRA_m))
393 short ptirc = mcs->pxms_ptirc;
394 short divisor = mcs->pxms_ptper * 6;
397 pxmc_irc_16bit_commindx(mcs, mcs->pxms_rp >> PXMC_SUBDIV(mcs));
402 res = pxmc_inp_rocon_ptofs_from_index_poll(mcs, 0);
404 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
406 pxmc_set_flag(mcs, PXMS_PTI_b);
407 pxmc_set_flag(mcs, PXMS_PHA_b);
412 hal_pos = pxmc_lpc_bdc_hal_pos_table[pxmc_rocon_bldc_hal_rd(mcs)];
417 pxmc_rocon_process_hal_error(mcs);
421 if (mcs->pxms_halerc)
424 ptindx = (hal_pos * ptirc + divisor / 2) / divisor;
426 if (!(mcs->pxms_flg & PXMS_PTI_m) || (mcs->pxms_flg & PXMS_PRA_m))
428 if (((hal_pos != mcs->pxms_hal) && (mcs->pxms_hal != 0x40)) && 1)
430 short ptindx_prev = (mcs->pxms_hal * ptirc + divisor / 2) / divisor;;
432 if ((ptindx > ptindx_prev + ptirc / 2) ||
433 (ptindx_prev > ptindx + ptirc / 2))
435 ptindx = (ptindx_prev + ptindx - ptirc) / 2;
442 ptindx = (ptindx_prev + ptindx) / 2;
445 mcs->pxms_ptindx = ptindx;
447 mcs->pxms_ptofs = (mcs->pxms_ap >> PXMC_SUBDIV(mcs)) + mcs->pxms_ptshift - ptindx;
449 pxmc_set_flag(mcs, PXMS_PTI_b);
450 pxmc_clear_flag(mcs, PXMS_PRA_b);
454 if (!(mcs->pxms_flg & PXMS_PTI_m))
455 mcs->pxms_ptindx = ptindx;
458 /* if phase table position to mask is know do fine phase table alignment */
459 if (mcs->pxms_cfg & PXMS_CFG_I2PT_m) {
461 res = pxmc_inp_rocon_ptofs_from_index_poll(mcs, 0);
463 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
465 pxmc_set_flag(mcs, PXMS_PTI_b);
466 pxmc_set_flag(mcs, PXMS_PHA_b);
470 mcs->pxms_hal = hal_pos;
476 /*wind_current[0]=(ADC->ADDR0 & 0xFFF0)>>4;*/
477 /* FIXME - check winding current against limit */
478 /* pxmc_set_errno(mcs, PXMS_E_WINDCURRENT); */
482 ptvang = mcs->pxms_ptvang;
486 ene = mcs->pxms_flg & PXMS_BSY_m? mcs->pxms_me: 0;
490 indx = mcs->pxms_ptindx;
492 /* tuning of magnetic field/voltage advance angle */
493 indx += (mcs->pxms_s1 * mcs->pxms_as) >> (PXMC_SUBDIV(mcs) + 8);
498 /* Generating direction of stator mag. field for backward torque */
501 if ((indx -= ptvang) < 0)
502 indx += mcs->pxms_ptirc;
506 /* Generating direction of stator mag. field for forward torque */
507 if ((indx += ptvang) >= mcs->pxms_ptirc)
508 indx -= mcs->pxms_ptirc;
511 if (mcs->pxms_ptscale_mult)
512 indx = ((unsigned long)indx * mcs->pxms_ptscale_mult) >> mcs->pxms_ptscale_shift;
514 pwm1 = mcs->pxms_ptptr1[indx];
515 pwm2 = mcs->pxms_ptptr2[indx];
516 pwm3 = mcs->pxms_ptptr3[indx];
518 #ifdef PXMC_WITH_PT_ZIC
519 if (labs(mcs->pxms_as) < (10 << PXMC_SUBDIV(mcs)))
521 pwm1 &= ~PXMC_PT_ZIC_MASK;
522 pwm2 &= ~PXMC_PT_ZIC_MASK;
523 pwm3 &= ~PXMC_PT_ZIC_MASK;
525 #endif /*PXMC_WITH_PT_ZIC*/
527 /* Default phase-table amplitude is 0x7fff, ene max is 0x7fff */
528 /* Initialized CTM4 PWM period is 0x200 => divide by value about 2097024 */
530 unsigned long pwm_dc = pxmc_rocon_pwm_magnitude * (unsigned long)ene;
531 if (pwm1 & PXMC_PT_ZIC_MASK)
534 pwm1 = (((unsigned long long)pwm1 * pwm_dc) >> (15 + 15)) | 0x4000;
535 if (pwm2 & PXMC_PT_ZIC_MASK)
538 pwm2 = (((unsigned long long)pwm2 * pwm_dc) >> (15 + 15)) | 0x4000;
539 if (pwm3 & PXMC_PT_ZIC_MASK)
542 pwm3 = (((unsigned long long)pwm3 * pwm_dc) >> (15 + 15)) | 0x4000;
544 pxmc_rocon_pwm3ph_wr(mcs, pwm1, pwm2, pwm3);
548 pxmc_rocon_pwm3ph_wr(mcs, 0, 0, 0);
555 * pxmc_rocon_pwm2ph_wr - Output of the 2-phase stepper motor PWM to the hardware
556 * @mcs: Motion controller state information
558 /*static*/ inline void
559 pxmc_rocon_pwm2ph_wr(pxmc_state_t *mcs, short pwm1, short pwm2)
561 volatile uint32_t *pwm_reg_ap, *pwm_reg_an, *pwm_reg_bp, *pwm_reg_bn;
562 int chan = mcs->pxms_out_info;
564 pwm_reg_bn = pxmc_rocon_pwm_chan2reg(chan + 0);
565 pwm_reg_bp = pxmc_rocon_pwm_chan2reg(chan + 1);
566 pwm_reg_an = pxmc_rocon_pwm_chan2reg(chan + 2);
567 pwm_reg_ap = pxmc_rocon_pwm_chan2reg(chan + 3);
570 *pwm_reg_bp = pwm2 | 0x4000;
574 *pwm_reg_bn = -pwm2 | 0x4000;
578 *pwm_reg_ap = pwm1 | 0x4000;
582 *pwm_reg_an = -pwm1 | 0x4000;
587 * pxmc_rocon_pwm2ph_out - Phase output of the 2-phase stepper motor PWM
588 * @mcs: Motion controller state information
591 pxmc_rocon_pwm2ph_out(pxmc_state_t *mcs)
593 typeof(mcs->pxms_ptvang) ptvang;
601 if(!(mcs->pxms_flg&PXMS_PTI_m) || !(mcs->pxms_flg&PXMS_PHA_m) ||
602 (mcs->pxms_flg&PXMS_PRA_m)){
604 short ptirc=mcs->pxms_ptirc;
607 pxmc_irc_16bit_commindx(mcs, mcs->pxms_rp >> PXMC_SUBDIV(mcs));
612 res = pxmc_inp_rocon_ptofs_from_index_poll(mcs, 0);
614 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
616 pxmc_set_flag(mcs, PXMS_PTI_b);
617 pxmc_set_flag(mcs, PXMS_PHA_b);
622 ptindx = mcs->pxms_ptindx;
624 if(0 && (!(mcs->pxms_flg&PXMS_PTI_m) || (mcs->pxms_flg&PXMS_PRA_m))) {
626 mcs->pxms_ptindx = ptindx;
628 mcs->pxms_ptofs = (mcs->pxms_ap >> PXMC_SUBDIV(mcs)) + mcs->pxms_ptshift - ptindx;
630 pxmc_set_flag(mcs, PXMS_PTI_b);
631 pxmc_clear_flag(mcs, PXMS_PRA_b);
633 /* if phase table position to mask is know do fine phase table alignment */
634 //if(mcs->pxms_cfg & PXMS_CFG_I2PT_m)
635 // lpc_qei_setup_index_catch(&lpc_qei_state);
638 if(!(mcs->pxms_flg&PXMS_PTI_m))
639 mcs->pxms_ptindx = ptindx;
645 /*wind_current[0]=(ADC->ADDR0 & 0xFFF0)>>4;*/
646 /* FIXME - check winding current against limit */
647 /* pxmc_set_errno(mcs, PXMS_E_WINDCURRENT); */
651 ptvang = mcs->pxms_ptvang;
655 ene = mcs->pxms_flg & PXMS_BSY_m? mcs->pxms_me: 0;
659 indx = mcs->pxms_ptindx;
661 /* tuning of magnetic field/voltage advance angle */
662 indx += (mcs->pxms_s1 * mcs->pxms_as) >> (PXMC_SUBDIV(mcs) + 8);
665 /* Generating direction of stator mag. field for backward torque */
667 if ((indx -= ptvang)<0)
668 indx += mcs->pxms_ptirc;
670 /* Generating direction of stator mag. field for forward torque */
671 if ((indx += ptvang) >= mcs->pxms_ptirc)
672 indx -= mcs->pxms_ptirc;
675 if (mcs->pxms_ptscale_mult)
676 indx = ((unsigned long)indx * mcs->pxms_ptscale_mult) >> mcs->pxms_ptscale_shift;
678 pwm1 = mcs->pxms_ptptr1[indx];
679 pwm2 = mcs->pxms_ptptr2[indx];
681 /* Default phase-table amplitude is 0x7fff, ene max is 0x7fff */
682 /* Initialized PWM period is 0x200 => divide by value about 2097024 */
684 unsigned long pwm_dc = pxmc_rocon_pwm_magnitude * (unsigned long)ene;
685 pwm1 = ((unsigned long long)pwm1 * pwm_dc) >> (15+15);
686 pwm2 = ((unsigned long long)pwm2 * pwm_dc) >> (15+15);
688 pxmc_rocon_pwm2ph_wr(mcs, pwm1, pwm2);
690 /*pxmc_lpc_wind_current_over_cnt = 0;*/
691 pxmc_rocon_pwm2ph_wr(mcs, 0, 0);
698 * pxmc_rocon_pwm_dc_out - DC motor CW and CCW PWM output
699 * @mcs: Motion controller state information
702 pxmc_rocon_pwm_dc_out(pxmc_state_t *mcs)
704 volatile uint32_t *pwm_reg_a, *pwm_reg_b;
705 int chan = mcs->pxms_out_info;
706 int ene = mcs->pxms_ene;
708 pwm_reg_a = pxmc_rocon_pwm_chan2reg(chan + 0);
709 pwm_reg_b = pxmc_rocon_pwm_chan2reg(chan + 1);
715 ene = (ene * (pxmc_rocon_pwm_magnitude + 5)) >> 15;
717 *pwm_reg_b = ene | 0x4000;
721 ene = (ene * (pxmc_rocon_pwm_magnitude + 5)) >> 15;
723 *pwm_reg_a = ene | 0x4000;
729 /*******************************************************************/
730 /* PXMCC - PXMC coprocessor support and communication */
732 void pxmcc_pxmc_ptofs2mcc(pxmc_state_t *mcs, int enable_update)
734 volatile pxmcc_axis_data_t *mcc_axis = pxmc_rocon_mcs2pxmcc(mcs);
735 int inp_chan=mcs->pxms_inp_info;
739 if (mcc_axis != NULL) {
740 if (enable_update >= 0)
741 mcc_axis->ptirc = 0xffffffff;
742 ptofs = mcs->pxms_ptofs - pxmc_rocon_irc_offset[inp_chan];
743 irc = fpga_irc[inp_chan]->count;
744 ptofs = (int16_t)(ptofs - irc) + irc;
745 mcc_axis->ptofs = ptofs;
746 if (enable_update > 0) {
747 mcc_axis->ptirc = mcs->pxms_ptirc;
753 void pxmcc_axis_get_cur_dq_filt_raw(pxmc_state_t *mcs,
754 int32_t *p_cur_d_raw, int32_t *p_cur_q_raw)
756 volatile pxmcc_axis_data_t *mcc_axis = pxmc_rocon_mcs2pxmcc(mcs);
757 pxmc_rocon_state_t *mcsrc = pxmc_state2rocon_state(mcs);
758 uint32_t cur_d_cum = mcc_axis->cur_d_cum;
759 uint32_t cur_q_cum = mcc_axis->cur_q_cum;
763 cur_d = cur_d_cum - mcsrc->cur_d_cum_prev;
764 mcsrc->cur_d_cum_prev = cur_d_cum;
765 cur_q = cur_q_cum - mcsrc->cur_q_cum_prev;
766 mcsrc->cur_q_cum_prev = cur_q_cum;
768 *p_cur_d_raw = cur_d;
769 *p_cur_q_raw = cur_q;
773 void pxmcc_axis_cur_dq_raw2filt(int *p_cur, int32_t cur_raw)
777 cur_div = cur_raw & 0x1f;
778 cur = cur_raw / cur_div;
779 cur += (1 << 11) | 0x20;
784 void pxmcc_axis_get_cur_dq_filt(pxmc_state_t *mcs, int *p_cur_d, int *p_cur_q)
789 pxmcc_axis_get_cur_dq_filt_raw(mcs, &cur_d_raw, &cur_q_raw);
791 pxmcc_axis_cur_dq_raw2filt(p_cur_d, cur_d_raw);
792 pxmcc_axis_cur_dq_raw2filt(p_cur_q, cur_q_raw);
796 void pxmcc_cur_ctrl_pi(int *p_pwm, int32_t *p_cur_err_sum,
797 int cur_err, short cur_ctrl_p, short cur_ctrl_i, int max_pwm)
800 int32_t cur_err_sum = *p_cur_err_sum;
802 pwm = (cur_err * cur_ctrl_p) >> 8;
805 cur_err_sum += cur_err * cur_ctrl_i;
809 pwm += cur_err_sum >> 16;
812 cur_err_sum -= (pwm - max_pwm) << 16;
814 } else if (-pwm > max_pwm) {
815 cur_err_sum -= (pwm + max_pwm) << 16;
818 *p_cur_err_sum = cur_err_sum;
823 pxmc_pxmcc_pwm3ph_out(pxmc_state_t *mcs)
825 if (!(mcs->pxms_flg & PXMS_PTI_m) || !(mcs->pxms_flg & PXMS_PHA_m) ||
826 (mcs->pxms_flg & PXMS_PRA_m)) {
828 short ptirc = mcs->pxms_ptirc;
829 short divisor = mcs->pxms_ptper * 6;
830 unsigned char hal_pos;
832 hal_pos = pxmc_lpc_bdc_hal_pos_table[pxmc_rocon_bldc_hal_rd(mcs)];
834 if (hal_pos == 0xff) {
836 pxmc_rocon_process_hal_error(mcs);
838 if (mcs->pxms_halerc)
841 ptindx = (hal_pos * ptirc + divisor / 2) / divisor;
843 if (!(mcs->pxms_flg & PXMS_PTI_m) || (mcs->pxms_flg & PXMS_PRA_m)) {
844 int set_ptofs_fl = 0;
845 int ptofs_enable_update = 0;
847 if (((hal_pos != mcs->pxms_hal) && (mcs->pxms_hal != 0x40)) && 1) {
848 short ptindx_prev = (mcs->pxms_hal * ptirc + divisor / 2) / divisor;;
850 if ((ptindx > ptindx_prev + ptirc / 2) ||
851 (ptindx_prev > ptindx + ptirc / 2)) {
852 ptindx = (ptindx_prev + ptindx - ptirc) / 2;
857 ptindx = (ptindx_prev + ptindx) / 2;
861 ptofs_enable_update = 1;
863 pxmc_set_flag(mcs, PXMS_PTI_b);
864 pxmc_clear_flag(mcs, PXMS_PRA_b);
866 if (!(mcs->pxms_flg & PXMS_PTI_m))
870 mcs->pxms_ptindx = ptindx;
871 mcs->pxms_ptofs = (mcs->pxms_ap >> PXMC_SUBDIV(mcs)) + mcs->pxms_ptshift - ptindx;
873 pxmcc_pxmc_ptofs2mcc(mcs, ptofs_enable_update);
876 /* if phase table position to mask is know do fine phase table alignment */
877 if (mcs->pxms_cfg & PXMS_CFG_I2PT_m) {
880 res = pxmc_inp_rocon_ptofs_from_index_poll(mcs, 0);
882 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
884 pxmcc_pxmc_ptofs2mcc(mcs, 1);
885 pxmc_set_flag(mcs, PXMS_PTI_b);
886 pxmc_set_flag(mcs, PXMS_PHA_b);
890 mcs->pxms_hal = hal_pos;
895 /*wind_current[0]=(ADC->ADDR0 & 0xFFF0)>>4;*/
896 /* FIXME - check winding current against limit */
897 /* pxmc_set_errno(mcs, PXMS_E_WINDCURRENT); */
901 int ene, pwm_d, pwm_q;
905 pwm_q = (pxmc_rocon_pwm_magnitude * ene) >> 15;
907 pxmcc_axis_pwm_dq_out(mcs, pwm_d, pwm_q);
909 if (mcs->pxms_flg & PXMS_ERR_m)
910 pxmc_rocon_pwm3ph_wr(mcs, 0, 0, 0);
917 pxmc_pxmcc_pwm2ph_out(pxmc_state_t *mcs)
919 if(!(mcs->pxms_flg&PXMS_PTI_m) || !(mcs->pxms_flg&PXMS_PHA_m) ||
920 (mcs->pxms_flg&PXMS_PRA_m)) {
923 /* Wait for index mark to align phases */
925 res = pxmc_inp_rocon_ptofs_from_index_poll(mcs, 0);
927 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
929 pxmcc_pxmc_ptofs2mcc(mcs, 1);
930 pxmc_set_flag(mcs, PXMS_PTI_b);
931 pxmc_set_flag(mcs, PXMS_PHA_b);
933 pxmcc_pxmc_ptofs2mcc(mcs, 0);
939 int ene, pwm_d, pwm_q;
943 pwm_q = (pxmc_rocon_pwm_magnitude * ene) >> 15;
945 pxmcc_axis_pwm_dq_out(mcs, pwm_d, pwm_q);
947 if (mcs->pxms_flg & PXMS_ERR_m)
948 pxmc_rocon_pwm2ph_wr(mcs, 0, 0);
955 * pxmc_pxmcc_nofb_inp - Dummy input for direct stepper motor control
956 * @mcs: Motion controller state information
959 pxmc_pxmcc_nofb_inp(pxmc_state_t *mcs)
965 * pxmc_pxmcc_nofb_con - Empty controller for direct stepper motor control
966 * @mcs: Motion controller state information
969 pxmc_pxmcc_nofb_con(pxmc_state_t *mcs)
971 mcs->pxms_ene=mcs->pxms_me;
976 pxmc_pxmcc_nofb2ph_out(pxmc_state_t *mcs)
978 pxmc_rocon_state_t *mcsrc = pxmc_state2rocon_state(mcs);
979 volatile pxmcc_axis_data_t *mcc_axis = pxmc_rocon_mcs2pxmcc(mcs);
983 pxmcc_axis_get_cur_dq_filt_raw(mcs, &cur_d_raw, &cur_q_raw);
985 if ((mcs->pxms_flg & PXMS_ERR_m) ||
986 !(mcs->pxms_flg & (PXMS_ENO_m | PXMS_ENR_m))) {
987 pxmc_rocon_pwm2ph_wr(mcs, 0, 0);
988 pxmcc_axis_pwm_dq_out(mcs, 0, 0);
989 mcc_axis->steps_inc = 0;
990 mcsrc->cur_d_err_sum = 0;
991 mcsrc->cur_q_err_sum = 0;
995 int cur_d_req, cur_d_err;
996 int cur_q_req, cur_q_err;
997 int max_pwm = mcs->pxms_me;
1000 pxmcc_axis_cur_dq_raw2filt(&cur_d, cur_d_raw);
1001 pxmcc_axis_cur_dq_raw2filt(&cur_q, cur_q_raw);
1006 cur_d_req = mcsrc->cur_hold;
1008 cur_d_err = cur_d_req - cur_d;
1010 pxmcc_cur_ctrl_pi(&pwm_d, &mcsrc->cur_d_err_sum, cur_d_err,
1011 mcsrc->cur_d_p, mcsrc->cur_d_i, max_pwm);
1013 /* pwm_d = (pxmc_rocon_pwm_magnitude * ene) >> 15; */
1017 cur_q_err = cur_q_req - cur_q;
1019 pxmcc_cur_ctrl_pi(&pwm_q, &mcsrc->cur_q_err_sum, cur_q_err,
1020 mcsrc->cur_q_p, mcsrc->cur_q_i, max_pwm);
1022 pxmcc_axis_pwm_dq_out(mcs, pwm_d, pwm_q);
1024 mcs->pxms_ap=mcs->pxms_rp;
1025 mcs->pxms_as=mcs->pxms_rs;
1026 mcc_axis->steps_lim = mcc_axis->steps_cnt + 6;
1028 stpinc = mcs->pxms_rs;
1029 mcc_axis->steps_inc = stpinc;
1031 /* stpinc /= (mcs->pxms_ptirc << PXMC_SUBDIV(mcs)); */
1032 /* pxms_ptscale_mult; pxms_ptscale_shift; */
1038 int pxmcc_axis_setup(pxmc_state_t *mcs, int mode)
1040 volatile pxmcc_data_t *mcc_data = pxmc_rocon_mcc_data();
1041 volatile pxmcc_axis_data_t *mcc_axis = pxmc_rocon_mcs2pxmcc(mcs);
1045 uint32_t pwmtx_info;
1046 uint32_t pwmtx_info_dummy = 27;
1052 if (mcc_axis == NULL)
1055 if (mcc_data->common.fwversion != PXMCC_FWVERSION)
1058 mcc_axis->ccflg = 0;
1059 mcc_axis->mode = PXMCC_MODE_IDLE;
1061 mcc_data->common.pwm_cycle = PXMC_LXPWR_PWM_CYCLE;
1063 ptirc = mcs->pxms_ptirc;
1064 ull = (1ULL << 32) * mcs->pxms_ptper;
1065 ptreci = (ull + ptirc / 2) / ptirc;
1067 mcc_axis->ptreci = ptreci;
1069 pxmcc_pxmc_ptofs2mcc(mcs, 0);
1071 inp_info = (char*)&fpga_irc[mcs->pxms_inp_info]->count - (char*)fpga_irc[0];
1072 inp_info += mcc_data->common.irc_base;
1075 case PXMCC_MODE_IDLE:
1078 case PXMCC_MODE_BLDC:
1081 case PXMCC_MODE_STEPPER_WITH_IRC:
1084 case PXMCC_MODE_STEPPER:
1086 mcc_axis->ptreci = 1;
1087 inp_info = (char*)&mcc_axis->steps_pos - (char*)mcc_data;
1091 mcc_axis->inp_info = inp_info;
1092 mcc_axis->out_info = mcs->pxms_out_info;
1094 pwm_chan = mcs->pxms_out_info;
1096 pwmtx_info = (pwmtx_info_dummy << 0) | (pwmtx_info_dummy << 8) |
1097 (pwmtx_info_dummy << 16) | (pwmtx_info_dummy << 24);
1099 for (i = phcnt; --i >= 0; ) {
1100 volatile uint32_t *pwm_reg;
1101 volatile uint32_t *pwm_reg_base = fpga_lx_master_transmitter_base;
1105 pwm_reg = pxmc_rocon_pwm_chan2reg(pwm_chan + i);
1106 if (pwm_reg == &pxmc_rocon_pwm_dummy_reg) {
1107 pwmtx_info |= pwmtx_info_dummy;
1109 pwmtx_info |= pwm_reg - pwm_reg_base;
1113 mcc_axis->pwmtx_info = pwmtx_info;
1115 mcc_axis->mode = mode;
1117 mcc_axis->ccflg = 0;
1118 mcc_axis->pwm_dq = 0;
1119 mcc_axis->steps_lim = mcc_axis->steps_cnt;
1120 mcc_axis->steps_inc = 0;
1121 mcc_axis->steps_pos = 0;
1123 if (mode != PXMCC_MODE_STEPPER) {
1124 pxmcc_pxmc_ptofs2mcc(mcs, 1);
1129 /*******************************************************************/
1131 volatile void *pxmc_rocon_rx_data_hist_buff;
1132 volatile void *pxmc_rocon_rx_data_hist_buff_end;
1133 int pxmc_rocon_rx_data_hist_mode;
1135 uint32_t pxmc_rocon_rx_last_irq;
1136 uint32_t pxmc_rocon_rx_cycle_time;
1137 uint32_t pxmc_rocon_rx_irq_latency;
1138 uint32_t pxmc_rocon_rx_irq_latency_max;
1140 IRQ_HANDLER_FNC(pxmc_rocon_rx_done_isr)
1144 ir = ROCON_RX_TIM->IR & LPC_TIM_IR_ALL_m;
1145 ROCON_RX_TIM->IR = ir;
1146 if (ir & LPC_TIM_IR_CR1INT_m) {
1148 cr0 = ROCON_RX_TIM->CR0;
1149 cr1 = ROCON_RX_TIM->CR1;
1151 pxmc_rocon_rx_cycle_time = cr1 - pxmc_rocon_rx_last_irq;
1152 pxmc_rocon_rx_last_irq = cr1;
1154 hal_gpio_set_value(T2MAT0_PIN, 1);
1155 hal_gpio_set_value(T2MAT1_PIN, 0);
1156 hal_gpio_set_value(T2MAT0_PIN, 0);
1158 if (pxmc_rocon_rx_data_hist_buff >= pxmc_rocon_rx_data_hist_buff_end)
1159 pxmc_rocon_rx_data_hist_buff = NULL;
1161 if (pxmc_rocon_rx_data_hist_buff != NULL) {
1162 if (pxmc_rocon_rx_data_hist_mode == 0) {
1164 volatile uint32_t *pwm_reg = fpga_lx_master_transmitter_base + 8;
1165 volatile uint32_t *rec_reg = fpga_lx_master_receiver_base + 8;
1166 uint16_t *pbuf = (uint16_t *)pxmc_rocon_rx_data_hist_buff;
1167 for (i = 0; i < 8; i++) {
1168 *(pbuf++) = *(rec_reg++);
1170 for (i = 0; i < 8; i++) {
1171 *(pbuf++) = *(pwm_reg++);
1173 pxmc_rocon_rx_data_hist_buff = pbuf;
1174 } else if (pxmc_rocon_rx_data_hist_mode == 1) {
1176 uint32_t *pbuf = (uint32_t *)pxmc_rocon_rx_data_hist_buff;
1177 pxmcc_data_t *mcc_data = pxmc_rocon_mcc_data();
1178 pxmcc_axis_data_t *mcc_axis = mcc_data->axis + 0;
1179 uint32_t *ptumbl = (uint32_t *)mcc_axis;
1181 for (i = 0; i < 16; i++)
1182 *(pbuf++) = *(ptumbl++);
1184 pxmc_rocon_rx_data_hist_buff = pbuf;
1188 pxmc_rocon_rx_irq_latency = ROCON_RX_TIM->TC - cr1;
1189 if (pxmc_rocon_rx_irq_latency > pxmc_rocon_rx_irq_latency_max)
1190 pxmc_rocon_rx_irq_latency_max = pxmc_rocon_rx_irq_latency;
1192 #ifdef PXMC_ROCON_TIMED_BY_RX_DONE
1195 #endif /*PXMC_ROCON_TIMED_BY_RX_DONE*/
1202 pxmc_rocon_rx_done_isr_setup(irq_handler_t rx_done_isr_handler)
1205 disable_irq(ROCON_RX_IRQn);
1207 hal_pin_conf_set(T2MAT0_PIN, PORT_CONF_GPIO_OUT_LO);
1208 hal_pin_conf_set(T2MAT1_PIN, PORT_CONF_GPIO_OUT_LO);
1209 hal_pin_conf(T2CAP0_PIN);
1210 hal_pin_conf(T2CAP1_PIN);
1212 hal_gpio_direction_output(T2MAT0_PIN, 1);
1213 hal_gpio_direction_output(T2MAT1_PIN, 0);
1214 hal_gpio_set_value(T2MAT0_PIN, 0);
1216 /* Enable CLKOUT pin function, source CCLK, divide by 1 */
1217 LPC_SC->CLKOUTCFG = 0x0100;
1219 request_irq(ROCON_RX_IRQn, rx_done_isr_handler, 0, NULL,NULL);
1221 ROCON_RX_TIM->TCR = 0;
1222 ROCON_RX_TIM->CTCR = 0;
1223 ROCON_RX_TIM->PR = 0; /* Divide by 1 */
1225 ROCON_RX_TIM->CCR = LPC_TIM_CCR_CAP0RE_m | LPC_TIM_CCR_CAP1FE_m |
1226 LPC_TIM_CCR_CAP1I_m;
1228 ROCON_RX_TIM->EMR = __val2mfld(LPC_TIM_EMR_EMC0_m, LPC_TIM_EMR_NOP) |
1229 __val2mfld(LPC_TIM_EMR_EMC1_m, LPC_TIM_EMR_NOP);
1231 ROCON_RX_TIM->MCR = 0; /* No IRQ on MRx */
1232 ROCON_RX_TIM->TCR = LPC_TIM_TCR_CEN_m; /* Enable timer counting */
1233 enable_irq(ROCON_RX_IRQn); /* Enable interrupt */
1240 pxmc_rocon_pwm_master_init(void)
1246 unsigned receiver_done_div = 1;
1247 #ifdef LXPWR_WITH_SIROLADC
1248 unsigned lxpwr_header = 1;
1249 unsigned lxpwr_words = 1 + 8 * 2 + 2;
1250 unsigned lxpwr_chips = 2;
1251 unsigned lxpwr_chip_pwm_cnt = 8;
1252 #else /*LXPWR_WITH_SIROLADC*/
1253 unsigned lxpwr_header = 0;
1254 unsigned lxpwr_words = 8;
1255 unsigned lxpwr_chips = 2;
1256 unsigned lxpwr_chip_pwm_cnt = 8;
1257 #endif /*LXPWR_WITH_SIROLADC*/
1259 #ifdef PXMC_ROCON_TIMED_BY_RX_DONE
1260 receiver_done_div = 5;
1261 #endif /*PXMC_ROCON_TIMED_BY_RX_DONE*/
1263 *fpga_lx_master_reset = 1;
1264 *fpga_lx_master_transmitter_reg = 0;
1265 *fpga_lx_master_transmitter_cycle = PXMC_LXPWR_PWM_CYCLE; /* 50 MHz -> 20 kHz */
1266 *fpga_lx_master_receiver_done_div = receiver_done_div << 8;
1268 for (i = 0; i < LX_MASTER_DATA_OFFS + lxpwr_words * lxpwr_chips; i++)
1269 fpga_lx_master_receiver_base[i] = 0;
1271 word_slot = LX_MASTER_DATA_OFFS;
1272 fpga_lx_master_receiver_base[grp_in++] = (word_slot << 8) | lxpwr_words;
1273 fpga_lx_master_receiver_base[grp_in++] = 0x0000;
1275 for (i = 0; i < LX_MASTER_DATA_OFFS + lxpwr_words * lxpwr_chips; i++)
1276 fpga_lx_master_transmitter_base[i] = 0;
1278 word_slot = LX_MASTER_DATA_OFFS + lxpwr_header + lxpwr_chip_pwm_cnt;
1279 fpga_lx_master_transmitter_base[grp_out++] = (word_slot << 8) | lxpwr_words;
1280 #ifdef LXPWR_WITH_SIROLADC
1281 fpga_lx_master_transmitter_base[word_slot] = 0xc100 | (lxpwr_words - 1);
1282 #endif /*LXPWR_WITH_SIROLADC*/
1284 word_slot = LX_MASTER_DATA_OFFS + 0;
1285 fpga_lx_master_transmitter_base[grp_out++] = (word_slot << 8) | lxpwr_words;
1286 #ifdef LXPWR_WITH_SIROLADC
1287 fpga_lx_master_transmitter_base[word_slot] = 0xc100 | (lxpwr_words - 1);
1288 #endif /*LXPWR_WITH_SIROLADC*/
1290 fpga_lx_master_transmitter_base[grp_out++] = 0x0000;
1292 *fpga_lx_master_reset = 0;
1293 *fpga_lx_master_transmitter_cycle = PXMC_LXPWR_PWM_CYCLE; /* 50 MHz -> 20 kHz */
1294 *fpga_lx_master_receiver_done_div = receiver_done_div << 8;
1299 int pxmc_ptofs_from_index(pxmc_state_t *mcs, unsigned long irc,
1300 unsigned long index_irc, int diff2err)
1305 ofs = ofsl = index_irc - mcs->pxms_ptmark;
1309 diff = (unsigned short)ofs - (unsigned short)mcs->pxms_ptofs;
1310 if (diff >= mcs->pxms_ptirc / 2)
1311 diff -= mcs->pxms_ptirc;
1312 if (diff <= -mcs->pxms_ptirc / 2)
1313 diff += mcs->pxms_ptirc;
1316 if(diff >= mcs->pxms_ptirc / 6) {
1321 diff = (unsigned long)ofsl - irc;
1322 ofs = ofsl - (diff / mcs->pxms_ptirc) * mcs->pxms_ptirc;
1325 mcs->pxms_ptofs = ofs;
1331 * pxmc_dummy_con - Dummy controller for synchronous BLDC/PMSM/steper drive
1332 * @mcs: Motion controller state information
1335 pxmc_dummy_con(pxmc_state_t *mcs)
1340 int pxmc_rocon_hh_gd10(pxmc_state_t *mcs);
1341 int pxmc_rocon_hh_gd20(pxmc_state_t *mcs);
1342 int pxmc_rocon_hh_gd30(pxmc_state_t *mcs);
1343 int pxmc_rocon_hh_gd40(pxmc_state_t *mcs);
1344 int pxmc_rocon_hh_gd50(pxmc_state_t *mcs);
1345 int pxmc_rocon_hh_gd90(pxmc_state_t *mcs);
1347 /* initialize for hard home */
1349 pxmc_rocon_hh_gi(pxmc_state_t *mcs)
1351 pxmc_set_flag(mcs,PXMS_BSY_b);
1352 #if 0 /* config and speed already set in pxmc_hh */
1354 spd >>= mcs->pxms_cfg & PXMS_CFG_HSPD_m;
1356 if(mcs->pxms_cfg & PXMS_CFG_HDIR_m)
1358 mcs->pxms_gen_hsp = spd;
1361 mcs->pxms_gen_htim = 16;
1362 mcs->pxms_do_gen = pxmc_rocon_hh_gd10;
1363 return pxmc_rocon_hh_gd10(mcs);
1366 /* fill initial mark filter and then decide */
1368 pxmc_rocon_hh_gd10(pxmc_state_t *mcs)
1372 if(mcs->pxms_flg & PXMS_ERR_m)
1373 return pxmc_spdnext_gend(mcs);
1375 pxmc_spd_gacc(&(mcs->pxms_rs), 0, mcs->pxms_ma);
1376 mcs->pxms_rp += mcs->pxms_rs;
1378 mark = pxmc_inp_rocon_is_mark(mcs);
1380 if (mcs->pxms_gen_htim) {
1381 mcs->pxms_gen_htim--;
1385 if (!(mcs->pxms_cfg & PXMS_CFG_HLS_m)) {
1386 /* limit switch is not used */
1387 pxmc_inp_rocon_is_index_edge(mcs);
1388 mcs->pxms_do_gen = pxmc_rocon_hh_gd50;
1393 /* go out from switch */
1394 mcs->pxms_do_gen = pxmc_rocon_hh_gd20;
1396 /* switch is off -> look for it */
1397 mcs->pxms_do_gen = pxmc_rocon_hh_gd30;
1402 /* go out from switch */
1404 pxmc_rocon_hh_gd20(pxmc_state_t *mcs)
1408 if(mcs->pxms_flg & PXMS_ERR_m)
1409 return pxmc_spdnext_gend(mcs);
1411 mark = pxmc_inp_rocon_is_mark(mcs);
1414 /* switch is off -> look for it again */
1415 mcs->pxms_do_gen = pxmc_rocon_hh_gd30;
1418 pxmc_spd_gacc(&(mcs->pxms_rs), -mcs->pxms_gen_hsp, mcs->pxms_ma);
1419 mcs->pxms_rp += mcs->pxms_rs;
1424 /* switch is off -> look for it */
1426 pxmc_rocon_hh_gd30(pxmc_state_t *mcs)
1431 if (mcs->pxms_flg & PXMS_ERR_m)
1432 return pxmc_spdnext_gend(mcs);
1434 pxmc_spd_gacc(&(mcs->pxms_rs), mcs->pxms_gen_hsp, mcs->pxms_ma);
1435 mcs->pxms_rp += mcs->pxms_rs;
1437 mark = pxmc_inp_rocon_is_mark(mcs);
1440 spd = mcs->pxms_gen_hsp >> 2; /* slow down */
1443 mcs->pxms_gen_hsp = spd;
1444 mcs->pxms_do_gen = pxmc_rocon_hh_gd40;
1450 /* switch is on -> find edge */
1452 pxmc_rocon_hh_gd40(pxmc_state_t *mcs)
1456 if (mcs->pxms_flg & PXMS_ERR_m)
1457 return pxmc_spdnext_gend(mcs);
1459 mark = pxmc_inp_rocon_is_mark(mcs);
1462 if (mcs->pxms_cfg & PXMS_CFG_HRI_m) {
1463 pxmc_inp_rocon_is_index_edge(mcs);
1464 mcs->pxms_do_gen = pxmc_rocon_hh_gd50;
1466 pxmc_inp_rocon_ap_zero(mcs);
1467 mcs->pxms_do_gen = pxmc_stop_gi;
1471 pxmc_spd_gacc(&(mcs->pxms_rs), -mcs->pxms_gen_hsp, mcs->pxms_ma);
1472 mcs->pxms_rp += mcs->pxms_rs;
1477 /* calibrate on revolution index */
1479 pxmc_rocon_hh_gd50(pxmc_state_t *mcs)
1481 if (mcs->pxms_flg & PXMS_ERR_m)
1482 return pxmc_spdnext_gend(mcs);
1484 pxmc_spd_gacc(&(mcs->pxms_rs), mcs->pxms_gen_hsp, mcs->pxms_ma);
1485 mcs->pxms_rp += mcs->pxms_rs;
1487 if (pxmc_inp_rocon_is_index_edge(mcs)){
1488 pxmc_inp_rocon_irc_offset_from_index(mcs);
1489 mcs->pxms_do_gen = pxmc_stop_gi;
1495 pxmc_call_t *pxmc_get_hh_gi_4axis(pxmc_state_t *mcs)
1497 return pxmc_rocon_hh_gi;
1500 pxmc_rocon_state_t mcs0 =
1508 pxmc_pid_con /*pxmc_dummy_con*/,
1510 pxmc_rocon_pwm_dc_out /*pxmc_rocon_pwm3ph_out*/,
1514 pxmc_inp_rocon_ap2hw,
1515 pxms_ap: 0, pxms_as: 0,
1516 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1517 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
1520 pxms_ene: 0, pxms_erc: 0,
1521 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1522 pxms_me: 0x7e00/*0x7fff*/,
1524 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m * 0 |
1525 PXMS_CFG_HRI_m * 0 | PXMS_CFG_HDIR_m * 0 |
1526 PXMS_CFG_I2PT_m * 0 | 0x2,
1531 /*pxms_ptamp: 0x7fff,*/
1542 pxmc_rocon_state_t mcs1 =
1552 pxmc_rocon_pwm_dc_out,
1556 pxmc_inp_rocon_ap2hw,
1557 pxms_ap: 0, pxms_as: 0,
1558 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1559 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
1562 pxms_ene: 0, pxms_erc: 0,
1563 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1564 pxms_me: 0x7e00/*0x7fff*/,
1566 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m * 0 |
1567 PXMS_CFG_HRI_m * 0 | PXMS_CFG_HDIR_m * 0 |
1568 PXMS_CFG_I2PT_m * 0 | 0x2,
1572 /*pxms_ptamp: 0x7fff,*/
1577 pxmc_rocon_state_t mcs2 =
1587 pxmc_rocon_pwm_dc_out,
1591 pxmc_inp_rocon_ap2hw,
1592 pxms_ap: 0, pxms_as: 0,
1593 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1594 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
1597 pxms_ene: 0, pxms_erc: 0,
1598 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1599 pxms_me: 0x7e00/*0x7fff*/,
1601 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m * 0 |
1602 PXMS_CFG_I2PT_m * 0 | PXMS_CFG_HRI_m |
1603 PXMS_CFG_HDIR_m | 0x2,
1607 /*pxms_ptamp: 0x7fff,*/
1612 pxmc_rocon_state_t mcs3 =
1622 pxmc_rocon_pwm_dc_out,
1626 pxmc_inp_rocon_ap2hw,
1627 pxms_ap: 0, pxms_as: 0,
1628 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1629 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
1632 pxms_ene: 0, pxms_erc: 0,
1633 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1634 pxms_me: 0x7e00/*0x7fff*/,
1636 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m * 0 |
1637 PXMS_CFG_I2PT_m * 0 | PXMS_CFG_HRI_m |
1638 PXMS_CFG_HDIR_m * 0 | 0x2,
1642 /*pxms_ptamp: 0x7fff,*/
1647 pxmc_rocon_state_t mcs4 =
1657 pxmc_rocon_pwm_dc_out,
1661 pxmc_inp_rocon_ap2hw,
1662 pxms_ap: 0, pxms_as: 0,
1663 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1664 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
1667 pxms_ene: 0, pxms_erc: 0,
1668 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1669 pxms_me: 0x7e00/*0x7fff*/,
1671 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m * 0 |
1672 PXMS_CFG_HRI_m | PXMS_CFG_I2PT_m * 0 |
1673 PXMS_CFG_HDIR_m | 0x2,
1677 /*pxms_ptamp: 0x7fff,*/
1682 pxmc_rocon_state_t mcs5 =
1692 pxmc_rocon_pwm_dc_out,
1696 pxmc_inp_rocon_ap2hw,
1697 pxms_ap: 0, pxms_as: 0,
1698 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1699 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
1702 pxms_ene: 0, pxms_erc: 0,
1703 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1704 pxms_me: 0x7e00/*0x7fff*/,
1706 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m |
1707 PXMS_CFG_HRI_m | PXMS_CFG_I2PT_m * 0 |
1708 PXMS_CFG_HDIR_m | 0x2,
1712 /*pxms_ptamp: 0x7fff,*/
1717 pxmc_rocon_state_t mcs6 =
1727 pxmc_rocon_pwm_dc_out,
1731 pxmc_inp_rocon_ap2hw,
1732 pxms_ap: 0, pxms_as: 0,
1733 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1734 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
1737 pxms_ene: 0, pxms_erc: 0,
1738 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1739 pxms_me: 0x7e00/*0x7fff*/,
1741 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_I2PT_m * 0 |
1746 /*pxms_ptamp: 0x7fff,*/
1751 pxmc_rocon_state_t mcs7 =
1761 pxmc_rocon_pwm_dc_out,
1765 pxmc_inp_rocon_ap2hw,
1766 pxms_ap: 0, pxms_as: 0,
1767 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1768 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
1771 pxms_ene: 0, pxms_erc: 0,
1772 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1773 pxms_me: 0x7e00/*0x7fff*/,
1775 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_I2PT_m * 0 |
1780 /*pxms_ptamp: 0x7fff,*/
1785 pxmc_state_t *pxmc_main_arr[PXML_MAIN_CNT] =
1786 {&mcs0.base, &mcs1.base, &mcs2.base, &mcs3.base,
1787 &mcs4.base, &mcs5.base, &mcs6.base, &mcs7.base};
1790 pxmc_state_list_t pxmc_main_list =
1797 void pxmc_lpc_qei_callback_index(struct lpc_qei_state_t *qst, void *context)
1799 pxmc_state_t *mcs = (pxmc_state_t *)context;
1802 irc = qst->index_pos;
1804 if ((mcs->pxms_cfg & PXMS_CFG_I2PT_m) && (mcs->pxms_flg & PXMS_PTI_m))
1807 ofs = irc - mcs->pxms_ptmark;
1808 diff = ofs - mcs->pxms_ptofs;
1810 if (diff >= mcs->pxms_ptirc / 2)
1811 diff -= mcs->pxms_ptirc;
1813 if (diff <= -mcs->pxms_ptirc / 2)
1814 diff += mcs->pxms_ptirc;
1819 if (diff >= mcs->pxms_ptirc / 6)
1821 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
1825 mcs->pxms_ptofs = ofs;
1826 pxmc_set_flag(mcs, PXMS_PHA_b);
1830 ofs=irc-mcs->pxms_ptofs;
1831 if((unsigned short)ofs>=(unsigned short)mcs->pxms_ptirc) {
1833 ofs-=mcs->pxms_ptirc;
1835 ofs+=mcs->pxms_ptirc;
1838 mcs->pxms_ptmark=ofs;
1841 /*lpc_qei_set_cmpos(qst, 0, qst->index_pos-4000);*/
1844 int pxmc_lpc_pthalalign_callback(pxmc_state_t *mcs)
1848 lpc_qei_state_t *qst = &lpc_qei_state;
1849 int irc = lpc_qei_get_pos(qst);
1852 if (!qst->index_occ)
1855 idx_rel = qst->index_pos - irc;
1856 idx_rel %= mcs->pxms_ptirc;
1859 idx_rel += mcs->pxms_ptirc;
1861 ptofs = irc - mcs->pxms_ptofs;
1862 ptmark = ptofs + idx_rel;
1864 if ((unsigned short)ptmark >= mcs->pxms_ptirc)
1867 ptmark -= mcs->pxms_ptirc;
1869 ptmark += mcs->pxms_ptirc;
1872 if ((unsigned short)ptmark < mcs->pxms_ptirc)
1874 mcs->pxms_ptmark = ptmark;
1880 int pxmc_lpc_pthalalign(pxmc_state_t *mcs, int periods)
1885 pxmc_call_t *fin_fnc = pxmc_lpc_pthalalign_callback;
1886 lpc_qei_state_t *qst = &lpc_qei_state;
1888 mcs->pxms_cfg &= ~PXMS_CFG_I2PT_m;
1889 lpc_qei_setup_index_catch(qst);
1891 r2acq = ((long)mcs->pxms_ptirc << PXMC_SUBDIV(mcs)) * periods;
1892 spd = 1 << PXMC_SUBDIV(mcs);
1894 res = pxmc_pthalalign(mcs, r2acq, spd, fin_fnc);
1899 int pxmc_lpc_pthalalign_run(void)
1901 return pxmc_lpc_pthalalign(pxmc_main_list.pxml_arr[0], 20);
1904 static inline void pxmc_sfi_input(void)
1908 pxmc_for_each_mcs(var, mcs)
1910 /* PXMS_ENI_m - check if input (IRC) update is enabled */
1911 if (mcs->pxms_flg & PXMS_ENI_m)
1913 pxmc_call(mcs, mcs->pxms_do_inp);
1918 static inline void pxmc_sfi_controller_and_output(void)
1922 pxmc_for_each_mcs(var, mcs)
1924 /* PXMS_ENR_m - check if controller is enabled */
1925 if (mcs->pxms_flg & PXMS_ENR_m || mcs->pxms_flg & PXMS_ENO_m)
1928 /* If output only is enabled, we skip the controller */
1929 if (mcs->pxms_flg & PXMS_ENR_m)
1932 pxmc_call(mcs, mcs->pxms_do_con);
1934 /* PXMS_ERR_m - if axis in error state */
1935 if (mcs->pxms_flg & PXMS_ERR_m)
1939 /* for bushless motors, it is necessary to call do_out
1940 even if the controller is not enabled and PWM should be provided. */
1941 pxmc_call(mcs, mcs->pxms_do_out);
1946 static inline void pxmc_sfi_generator(void)
1950 pxmc_for_each_mcs(var, mcs)
1952 /* PXMS_ENG_m - check if requested value (position) generator is enabled */
1953 if (mcs->pxms_flg & PXMS_ENG_m)
1955 pxmc_call(mcs, mcs->pxms_do_gen);
1960 static inline void pxmc_sfi_dbg(void)
1964 pxmc_for_each_mcs(var, mcs)
1966 if (mcs->pxms_flg & PXMS_DBG_m)
1968 pxmc_call(mcs, mcs->pxms_do_deb);
1973 int pxmc_rocon_pthalalign_callback(pxmc_state_t *mcs)
1977 int inp_chan = mcs->pxms_inp_info;
1979 long irc = fpga_irc[inp_chan]->count;
1981 if (!pxmc_inp_rocon_is_index_edge(mcs))
1984 idx_rel = fpga_irc[inp_chan]->count_index - irc;
1985 idx_rel %= mcs->pxms_ptirc;
1987 idx_rel += mcs->pxms_ptirc;
1989 ptofs = irc-mcs->pxms_ptofs;
1990 ptmark = ptofs+idx_rel;
1992 if((unsigned short)ptmark >= mcs->pxms_ptirc) {
1994 ptmark -= mcs->pxms_ptirc;
1996 ptmark += mcs->pxms_ptirc;
1999 if((unsigned short)ptmark < mcs->pxms_ptirc) {
2000 mcs->pxms_ptmark = ptmark;
2005 int pxmc_rocon_pthalalign(pxmc_state_t *mcs, int periods)
2010 pxmc_call_t *fin_fnc = pxmc_rocon_pthalalign_callback;
2012 mcs->pxms_cfg&=~PXMS_CFG_I2PT_m;
2014 r2acq=((long)mcs->pxms_ptirc<<PXMC_SUBDIV(mcs))*periods;
2015 spd=1<<PXMC_SUBDIV(mcs);
2017 /* clear bit indicating previous index */
2018 pxmc_inp_rocon_is_index_edge(mcs);
2020 res=pxmc_pthalalign(mcs, r2acq, spd, fin_fnc);
2025 int pxmc_axis_rdmode(pxmc_state_t *mcs)
2027 if (mcs->pxms_do_out == pxmc_rocon_pwm2ph_out)
2028 return PXMC_AXIS_MODE_STEPPER_WITH_IRC;
2029 if (mcs->pxms_do_out == pxmc_rocon_pwm_dc_out)
2030 return PXMC_AXIS_MODE_DC;
2031 if (mcs->pxms_do_out == pxmc_rocon_pwm3ph_out)
2032 return PXMC_AXIS_MODE_BLDC;
2033 if (mcs->pxms_do_out == pxmc_pxmcc_pwm3ph_out)
2034 return PXMC_AXIS_MODE_BLDC_PXMCC;
2035 if (mcs->pxms_do_out == pxmc_pxmcc_pwm2ph_out)
2036 return PXMC_AXIS_MODE_STEPPER_WITH_IRC_PXMCC;
2037 if (mcs->pxms_do_out == pxmc_pxmcc_nofb2ph_out)
2038 return PXMC_AXIS_MODE_STEPPER_PXMCC;
2044 pxmc_axis_pt4mode(pxmc_state_t *mcs, int mode)
2046 static const typeof(*mcs->pxms_ptptr1) dummy0 = 0;
2049 if (mode == PXMC_AXIS_MODE_NOCHANGE)
2050 mode = pxmc_axis_rdmode(mcs);
2055 /* case PXMC_AXIS_MODE_STEPPER: */
2056 case PXMC_AXIS_MODE_STEPPER_PXMCC:
2057 case PXMC_AXIS_MODE_STEPPER_WITH_IRC:
2058 case PXMC_AXIS_MODE_STEPPER_WITH_IRC_PXMCC:
2059 res = pxmc_ptable_set_profile(mcs, &pxmc_ptprofile_sin, 0, 0);
2061 /*case PXMC_AXIS_MODE_STEPPER_WITH_PWM:*/
2062 case PXMC_AXIS_MODE_DC:
2063 /*profive some sane dummy values*/
2064 mcs->pxms_ptptr1 = (typeof(mcs->pxms_ptptr1))&dummy0;
2065 mcs->pxms_ptptr2 = (typeof(mcs->pxms_ptptr1))&dummy0;
2066 mcs->pxms_ptptr3 = (typeof(mcs->pxms_ptptr1))&dummy0;
2068 mcs->pxms_ptscale_mult=1;
2069 mcs->pxms_ptscale_shift=15;
2071 case PXMC_AXIS_MODE_BLDC:
2072 case PXMC_AXIS_MODE_BLDC_PXMCC:
2073 /* res = pxmc_init_ptable(mcs, PXMC_PTPROF_SIN3FUP); */
2074 #ifndef PXMC_WITH_PT_ZIC
2075 res = pxmc_ptable_set_profile(mcs, &pxmc_ptprofile_sin3phup, 0, 0);
2076 #else /*PXMC_WITH_PT_ZIC*/
2077 res = pxmc_ptable_set_profile(mcs, &pxmc_ptprofile_sin3phup_zic, 0, 0);
2078 #endif /*PXMC_WITH_PT_ZIC*/
2084 mcs->pxms_ptvang = pxmc_ptvang_deg2irc(mcs, 90);
2090 * pxmc_axis_mode - Sets axis mode.[extern API]
2091 * @mcs: Motion controller state information
2092 * @mode: 0 .. previous mode, 1 .. stepper motor mode,
2093 * 2 .. stepper motor with IRC feedback and PWM ,
2094 * 3 .. stepper motor with PWM control
2095 * 4 .. DC motor with IRC feedback and PWM
2099 pxmc_axis_mode(pxmc_state_t *mcs, int mode)
2104 pxmc_set_const_out(mcs, 0);
2105 pxmc_clear_flag(mcs, PXMS_ENI_b);
2106 pxmc_clear_flags(mcs,PXMS_ENO_m);
2107 /* Clear possible stall index flags from hardware */
2108 pxmc_inp_rocon_is_index_edge(mcs);
2109 pxmc_clear_flag(mcs, PXMS_PHA_b);
2110 pxmc_clear_flag(mcs, PXMS_PTI_b);
2113 prev_mode = pxmc_axis_rdmode(mcs);
2115 if (mode == PXMC_AXIS_MODE_NOCHANGE)
2120 mode = PXMC_AXIS_MODE_DC;
2122 if ((prev_mode == PXMC_AXIS_MODE_BLDC_PXMCC) ||
2123 (prev_mode == PXMCC_MODE_STEPPER_WITH_IRC))
2124 pxmcc_axis_setup(mcs, PXMCC_MODE_IDLE);
2126 res = pxmc_axis_pt4mode(mcs, mode);
2130 if (mcs->pxms_do_inp == pxmc_pxmcc_nofb_inp)
2131 mcs->pxms_do_inp = pxmc_inp_rocon_inp;
2132 if (mcs->pxms_do_con == pxmc_pxmcc_nofb_con)
2133 mcs->pxms_do_con = pxmc_pid_con;
2136 /*case PXMC_AXIS_MODE_STEPPER:*/
2137 case PXMC_AXIS_MODE_STEPPER_WITH_IRC:
2138 mcs->pxms_do_out = pxmc_rocon_pwm2ph_out;
2140 /*case PXMC_AXIS_MODE_STEPPER_WITH_PWM:*/
2141 case PXMC_AXIS_MODE_DC:
2142 mcs->pxms_do_out = pxmc_rocon_pwm_dc_out;
2144 case PXMC_AXIS_MODE_BLDC:
2145 mcs->pxms_do_out = pxmc_rocon_pwm3ph_out;
2147 case PXMC_AXIS_MODE_BLDC_PXMCC:
2148 if (pxmcc_axis_setup(mcs, PXMCC_MODE_BLDC) < 0)
2150 pxmcc_axis_enable(mcs, 1);
2151 mcs->pxms_do_out = pxmc_pxmcc_pwm3ph_out;
2153 case PXMC_AXIS_MODE_STEPPER_WITH_IRC_PXMCC:
2154 if (pxmcc_axis_setup(mcs, PXMCC_MODE_STEPPER_WITH_IRC) < 0)
2156 pxmcc_axis_enable(mcs, 1);
2157 mcs->pxms_do_out = pxmc_pxmcc_pwm2ph_out;
2159 case PXMC_AXIS_MODE_STEPPER_PXMCC:
2160 if (pxmcc_axis_setup(mcs, PXMCC_MODE_STEPPER) < 0)
2162 pxmcc_axis_enable(mcs, 1);
2163 mcs->pxms_do_inp = pxmc_pxmcc_nofb_inp;
2164 mcs->pxms_do_con = pxmc_pxmcc_nofb_con;
2165 mcs->pxms_do_out = pxmc_pxmcc_nofb2ph_out;
2171 /* Clear possible stall index flags from hardware */
2172 pxmc_inp_rocon_is_index_edge(mcs);
2173 /* Request new phases alignment for changed parameters */
2174 pxmc_clear_flag(mcs, PXMS_PHA_b);
2175 pxmc_clear_flag(mcs, PXMS_PTI_b);
2176 pxmc_set_flag(mcs, PXMS_ENI_b);
2180 void pxmc_sfi_isr(void)
2182 unsigned long spent = pxmc_fast_tick_time();
2185 pxmc_sfi_controller_and_output();
2186 pxmc_sfi_generator();
2188 /* Kick LX Master watchdog */
2189 if (pxmc_main_list.pxml_cnt != 0)
2190 *fpga_lx_master_transmitter_wdog = 1;
2192 spent = pxmc_fast_tick_time() - spent;
2194 if(spent > pxmc_sfi_spent_time_max)
2195 pxmc_sfi_spent_time_max = spent;
2199 int pxmc_clear_power_stop(void)
2204 int pxmc_process_state_check(unsigned long *pbusy_bits,
2205 unsigned long *perror_bits)
2208 unsigned short chan;
2209 unsigned long busy_bits = 0;
2210 unsigned long error_bits = 0;
2213 pxmc_for_each_mcs(chan, mcs) {
2215 flg |= mcs->pxms_flg;
2216 if (mcs->pxms_flg & PXMS_BSY_m)
2217 busy_bits |= 1 << chan;
2218 if (mcs->pxms_flg & PXMS_ERR_m)
2219 error_bits |= 1 << chan;
2222 if (appl_errstop_mode) {
2223 if((flg & PXMS_ENG_m) && (flg & PXMS_ERR_m)) {
2224 pxmc_for_each_mcs(chan, mcs) {
2225 if(mcs&&(mcs->pxms_flg & PXMS_ENG_m)) {
2232 if (pbusy_bits != NULL)
2233 *pbusy_bits = busy_bits;
2234 if (error_bits != NULL)
2235 *perror_bits = error_bits;
2245 if (!pxmc_main_list.pxml_cnt)
2248 pxmc_for_each_mcs(var, mcs)
2250 pxmc_set_const_out(mcs,0);
2253 pxmc_main_list.pxml_cnt = 0;
2259 int pxmc_initialize(void)
2264 pxmc_state_t *mcs = &mcs0.base;
2265 lpc_qei_state_t *qst = &lpc_qei_state;
2267 *fpga_irc_reset = 1;
2269 for (i = 0; i < 8; i++) {
2270 fpga_irc[i]->count = 0;
2271 fpga_irc[i]->count_index = 0;
2272 *fpga_irc_state[i] = FPGA_IRC_STATE_INDEX_EVENT_MASK;
2275 /* Initialize QEI module for IRC counting */
2276 pxmc_inp_lpc_qei_init(mcs->pxms_inp_info);
2278 /* Initialize QEI events processing */
2279 if (lpc_qei_setup_irq(qst) < 0)
2282 *fpga_irc_reset = 0;
2284 //res = pxmc_axis_pt4mode(mcs, PXMC_AXIS_MODE_BLDC);
2286 /*pxmc_ctm4pwm3f_wr(mcs, 0, 0, 0);*/
2287 //pxmc_rocon_pwm3ph_wr(mcs, 0, 0, 0);
2289 pxmc_rocon_pwm_master_init();
2290 #ifdef PXMC_ROCON_TIMED_BY_RX_DONE
2291 pxmc_rocon_rx_done_isr_setup(pxmc_rocon_rx_done_isr);
2292 #endif /*PXMC_ROCON_TIMED_BY_RX_DONE*/
2294 pxmc_main_list.pxml_cnt = 0;
2295 pxmc_dbg_hist = NULL;
2297 pxmc_main_list.pxml_cnt = PXML_MAIN_CNT;