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 uint32_t pxmc_rocon_vin_adc_last;
83 int pxmc_rocon_vin_act;
84 int pxmc_rocon_vin_ofs = 20978;
85 int pxmc_rocon_vin_mul = 32905;
86 int pxmc_rocon_vin_shr = 14;
89 void pxmc_rocon_vin_compute(void)
91 volatile uint32_t *vin_adc_reg;
95 vin_adc_reg = fpga_lx_master_receiver_base;
96 vin_adc_reg += LX_MASTER_DATA_OFFS + 1 + 8 * 2;
98 vin_adc = *vin_adc_reg;
100 vin_act = (int16_t)(vin_adc - pxmc_rocon_vin_adc_last);
101 pxmc_rocon_vin_adc_last = vin_adc;
103 vin_act = (pxmc_rocon_vin_ofs - vin_act) * pxmc_rocon_vin_mul;
104 vin_act >>= pxmc_rocon_vin_shr;
106 pxmc_rocon_vin_act = vin_act;
109 const uint8_t onesin10bits[1024]={
110 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,
111 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,
112 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,
113 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,
114 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,
115 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,
116 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,
117 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,
118 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,
119 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,
120 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,
121 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,
122 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,
123 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,
124 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,
125 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,
126 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,
127 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,
128 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,
129 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,
130 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,
131 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,
132 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,
133 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,
134 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,
135 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,
136 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,
137 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,
138 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,
139 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,
140 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,
141 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
145 pxmc_inp_rocon_inp(struct pxmc_state *mcs)
147 int chan=mcs->pxms_inp_info;
151 /* read position from hardware */
152 irc = fpga_irc[chan]->count;
153 irc += pxmc_rocon_irc_offset[chan];
154 pos = irc << PXMC_SUBDIV(mcs);
155 mcs->pxms_as = pos - mcs->pxms_ap;
158 /* Running of the motor commutator */
159 if (mcs->pxms_flg & PXMS_PTI_m)
160 pxmc_irc_16bit_commindx(mcs, irc);
166 pxmc_inp_rocon_is_mark(pxmc_state_t *mcs)
171 int chan=mcs->pxms_inp_info;
173 irc_state = *fpga_irc_state[chan];
175 mark = ((irc_state >> (ffs(FPGA_IRC_STATE_MARK_MASK) - 1)) ^
176 (mcs->pxms_cfg >> PXMS_CFG_HPS_b)) & 1;
178 filt = pxmc_rocon_mark_filt[chan];
179 filt = (filt << 1) | mark;
180 pxmc_rocon_mark_filt[chan] = filt;
182 return onesin10bits[filt & 0x03ff];
186 pxmc_inp_rocon_is_index_edge(pxmc_state_t *mcs)
190 int chan=mcs->pxms_inp_info;
192 irc_state = *fpga_irc_state[chan];
193 *fpga_irc_state[chan] = FPGA_IRC_STATE_INDEX_EVENT_MASK;
195 index = (irc_state >> (ffs(FPGA_IRC_STATE_INDEX_EVENT_MASK) - 1)) & 1;
201 pxmc_inp_rocon_adjust_to_irc_change(struct pxmc_state *mcs, long irc_diff)
203 long pos_diff = irc_diff << PXMC_SUBDIV(mcs);
205 mcs->pxms_ptofs += irc_diff;
207 mcs->pxms_ap += pos_diff;
208 mcs->pxms_rp += pos_diff;
213 pxmc_inp_rocon_irc_offset_from_index(struct pxmc_state *mcs)
215 int chan=mcs->pxms_inp_info;
219 irc_offset = -fpga_irc[chan]->count_index;
220 irc_diff = irc_offset - pxmc_rocon_irc_offset[chan];
221 pxmc_rocon_irc_offset[chan] = irc_offset;
222 return pxmc_inp_rocon_adjust_to_irc_change(mcs, irc_diff);
226 pxmc_inp_rocon_ap_zero(struct pxmc_state *mcs)
228 int chan=mcs->pxms_inp_info;
232 irc_offset = -fpga_irc[chan]->count;
233 irc_diff = irc_offset - pxmc_rocon_irc_offset[chan];
234 pxmc_rocon_irc_offset[chan] = irc_offset;
235 return pxmc_inp_rocon_adjust_to_irc_change(mcs, irc_diff);
239 pxmc_inp_rocon_ap2hw(struct pxmc_state *mcs)
241 int chan=mcs->pxms_inp_info;
245 irc = fpga_irc[chan]->count;
246 pos_diff = mcs->pxms_ap - (irc << PXMC_SUBDIV(mcs));
248 irc = pos_diff >> PXMC_SUBDIV(mcs);
250 /* Adjust phase table alignemt to modified IRC readout */
251 mcs->pxms_ptofs += irc - pxmc_rocon_irc_offset[chan];
253 pxmc_rocon_irc_offset[chan] = irc;
258 pxmc_inp_rocon_ptofs_from_index_poll(struct pxmc_state *mcs, int diff2err)
260 int chan=mcs->pxms_inp_info;
264 if (!(*fpga_irc_state[chan] & FPGA_IRC_STATE_INDEX_EVENT_MASK))
267 irc = fpga_irc[chan]->count + pxmc_rocon_irc_offset[chan];
268 index_irc = fpga_irc[chan]->count_index + pxmc_rocon_irc_offset[chan];
270 return pxmc_ptofs_from_index(mcs, irc, index_irc, diff2err);
273 uint32_t pxmc_rocon_receiver_dummy_reg;
275 static inline volatile uint32_t *
276 pxmc_rocon_receiver_chan2reg(unsigned chan)
278 volatile uint32_t *rec_reg;
281 return &pxmc_rocon_receiver_dummy_reg;
283 rec_reg = fpga_lx_master_receiver_base;
285 #ifdef LXPWR_WITH_SIROLADC
286 rec_reg += LX_MASTER_DATA_OFFS + 1 + (chan >> 3) * 3 + chan * 2;
287 #else /*LXPWR_WITH_SIROLADC*/
288 rec_reg += LX_MASTER_DATA_OFFS + chan;
289 #endif /*LXPWR_WITH_SIROLADC*/
295 pxmc_rocon_bldc_hal_rd(pxmc_state_t *mcs)
298 volatile uint32_t *rec_reg_a, *rec_reg_b, *rec_reg_c;
299 int chan = mcs->pxms_out_info;
302 #ifdef LXPWR_WITH_SIROLADC
304 #else /*LXPWR_WITH_SIROLADC*/
306 #endif /*LXPWR_WITH_SIROLADC*/
308 rec_reg_a = pxmc_rocon_receiver_chan2reg(chan + 0);
309 rec_reg_b = pxmc_rocon_receiver_chan2reg(chan + 1);
310 rec_reg_c = pxmc_rocon_receiver_chan2reg(chan + 2);
312 h = (rec_reg_a[hal_offs] >> 14) & 1;
313 h |= (rec_reg_b[hal_offs] >> 13) & 2;
314 h |= (rec_reg_c[hal_offs] >> 12) & 4;
316 /* return 3 bits corresponding to the HAL senzor input */
321 const unsigned char pxmc_lpc_bdc_hal_pos_table[8] =
333 const unsigned char pxmc_lpc_bdc_hal_pos_table[8] =
346 uint32_t pxmc_rocon_pwm_dummy_reg;
348 static inline volatile uint32_t *
349 pxmc_rocon_pwm_chan2reg(unsigned chan)
351 volatile uint32_t *pwm_reg;
354 return &pxmc_rocon_pwm_dummy_reg;
356 pwm_reg = fpga_lx_master_transmitter_base;
358 #ifdef LXPWR_WITH_SIROLADC
359 pwm_reg += LX_MASTER_DATA_OFFS + 1 + (chan >> 3) + chan;
360 #else /*LXPWR_WITH_SIROLADC*/
361 pwm_reg += LX_MASTER_DATA_OFFS + chan;
362 #endif /*LXPWR_WITH_SIROLADC*/
368 * pxmc_rocon_pwm3ph_wr - Output of the 3-phase PWM to the hardware
369 * @mcs: Motion controller state information
371 /*static*/ inline void
372 pxmc_rocon_pwm3ph_wr(pxmc_state_t *mcs, short pwm1, short pwm2, short pwm3)
374 volatile uint32_t *pwm_reg_a, *pwm_reg_b, *pwm_reg_c;
375 int chan = mcs->pxms_out_info;
377 pwm_reg_c = pxmc_rocon_pwm_chan2reg(chan + 0);
378 pwm_reg_b = pxmc_rocon_pwm_chan2reg(chan + 1);
379 pwm_reg_a = pxmc_rocon_pwm_chan2reg(chan + 2);
387 pxmc_rocon_process_hal_error(struct pxmc_state *mcs)
389 if (mcs->pxms_halerc >= HAL_ERR_SENSITIVITY * HAL_ERR_MAX_COUNT)
391 pxmc_set_errno(mcs, PXMS_E_HAL);
396 mcs->pxms_halerc += HAL_ERR_SENSITIVITY;
400 * pxmc_rocon_pwm3ph_out - Phase output for brush-less 3-phase motor
401 * @mcs: Motion controller state information
404 pxmc_rocon_pwm3ph_out(pxmc_state_t *mcs)
406 typeof(mcs->pxms_ptvang) ptvang;
408 unsigned char hal_pos;
416 if (!(mcs->pxms_flg & PXMS_PTI_m) || !(mcs->pxms_flg & PXMS_PHA_m) ||
417 (mcs->pxms_flg & PXMS_PRA_m))
420 short ptirc = mcs->pxms_ptirc;
421 short divisor = mcs->pxms_ptper * 6;
424 pxmc_irc_16bit_commindx(mcs, mcs->pxms_rp >> PXMC_SUBDIV(mcs));
429 res = pxmc_inp_rocon_ptofs_from_index_poll(mcs, 0);
431 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
433 pxmc_set_flag(mcs, PXMS_PTI_b);
434 pxmc_set_flag(mcs, PXMS_PHA_b);
439 hal_pos = pxmc_lpc_bdc_hal_pos_table[pxmc_rocon_bldc_hal_rd(mcs)];
444 pxmc_rocon_process_hal_error(mcs);
448 if (mcs->pxms_halerc)
451 ptindx = (hal_pos * ptirc + divisor / 2) / divisor;
453 if (!(mcs->pxms_flg & PXMS_PTI_m) || (mcs->pxms_flg & PXMS_PRA_m))
455 if (((hal_pos != mcs->pxms_hal) && (mcs->pxms_hal != 0x40)) && 1)
457 short ptindx_prev = (mcs->pxms_hal * ptirc + divisor / 2) / divisor;;
459 if ((ptindx > ptindx_prev + ptirc / 2) ||
460 (ptindx_prev > ptindx + ptirc / 2))
462 ptindx = (ptindx_prev + ptindx - ptirc) / 2;
469 ptindx = (ptindx_prev + ptindx) / 2;
472 mcs->pxms_ptindx = ptindx;
474 mcs->pxms_ptofs = (mcs->pxms_ap >> PXMC_SUBDIV(mcs)) + mcs->pxms_ptshift - ptindx;
476 pxmc_set_flag(mcs, PXMS_PTI_b);
477 pxmc_clear_flag(mcs, PXMS_PRA_b);
481 if (!(mcs->pxms_flg & PXMS_PTI_m))
482 mcs->pxms_ptindx = ptindx;
485 /* if phase table position to mask is know do fine phase table alignment */
486 if (mcs->pxms_cfg & PXMS_CFG_I2PT_m) {
488 res = pxmc_inp_rocon_ptofs_from_index_poll(mcs, 0);
490 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
492 pxmc_set_flag(mcs, PXMS_PTI_b);
493 pxmc_set_flag(mcs, PXMS_PHA_b);
497 mcs->pxms_hal = hal_pos;
503 /*wind_current[0]=(ADC->ADDR0 & 0xFFF0)>>4;*/
504 /* FIXME - check winding current against limit */
505 /* pxmc_set_errno(mcs, PXMS_E_WINDCURRENT); */
509 ptvang = mcs->pxms_ptvang;
513 ene = mcs->pxms_flg & PXMS_BSY_m? mcs->pxms_me: 0;
517 indx = mcs->pxms_ptindx;
519 /* tuning of magnetic field/voltage advance angle */
520 indx += (mcs->pxms_s1 * mcs->pxms_as) >> (PXMC_SUBDIV(mcs) + 8);
525 /* Generating direction of stator mag. field for backward torque */
528 if ((indx -= ptvang) < 0)
529 indx += mcs->pxms_ptirc;
533 /* Generating direction of stator mag. field for forward torque */
534 if ((indx += ptvang) >= mcs->pxms_ptirc)
535 indx -= mcs->pxms_ptirc;
538 if (mcs->pxms_ptscale_mult)
539 indx = ((unsigned long)indx * mcs->pxms_ptscale_mult) >> mcs->pxms_ptscale_shift;
541 pwm1 = mcs->pxms_ptptr1[indx];
542 pwm2 = mcs->pxms_ptptr2[indx];
543 pwm3 = mcs->pxms_ptptr3[indx];
545 #ifdef PXMC_WITH_PT_ZIC
546 if (labs(mcs->pxms_as) < (10 << PXMC_SUBDIV(mcs)))
548 pwm1 &= ~PXMC_PT_ZIC_MASK;
549 pwm2 &= ~PXMC_PT_ZIC_MASK;
550 pwm3 &= ~PXMC_PT_ZIC_MASK;
552 #endif /*PXMC_WITH_PT_ZIC*/
554 /* Default phase-table amplitude is 0x7fff, ene max is 0x7fff */
555 /* Initialized CTM4 PWM period is 0x200 => divide by value about 2097024 */
557 unsigned long pwm_dc = pxmc_rocon_pwm_magnitude * (unsigned long)ene;
558 if (pwm1 & PXMC_PT_ZIC_MASK)
561 pwm1 = (((unsigned long long)pwm1 * pwm_dc) >> (15 + 15)) | 0x4000;
562 if (pwm2 & PXMC_PT_ZIC_MASK)
565 pwm2 = (((unsigned long long)pwm2 * pwm_dc) >> (15 + 15)) | 0x4000;
566 if (pwm3 & PXMC_PT_ZIC_MASK)
569 pwm3 = (((unsigned long long)pwm3 * pwm_dc) >> (15 + 15)) | 0x4000;
571 pxmc_rocon_pwm3ph_wr(mcs, pwm1, pwm2, pwm3);
575 pxmc_rocon_pwm3ph_wr(mcs, 0, 0, 0);
582 * pxmc_rocon_pwm2ph_wr - Output of the 2-phase stepper motor PWM to the hardware
583 * @mcs: Motion controller state information
585 /*static*/ inline void
586 pxmc_rocon_pwm2ph_wr(pxmc_state_t *mcs, short pwm1, short pwm2)
588 volatile uint32_t *pwm_reg_ap, *pwm_reg_an, *pwm_reg_bp, *pwm_reg_bn;
589 int chan = mcs->pxms_out_info;
591 pwm_reg_bn = pxmc_rocon_pwm_chan2reg(chan + 0);
592 pwm_reg_bp = pxmc_rocon_pwm_chan2reg(chan + 1);
593 pwm_reg_an = pxmc_rocon_pwm_chan2reg(chan + 2);
594 pwm_reg_ap = pxmc_rocon_pwm_chan2reg(chan + 3);
597 *pwm_reg_bp = pwm2 | 0x4000;
601 *pwm_reg_bn = -pwm2 | 0x4000;
605 *pwm_reg_ap = pwm1 | 0x4000;
609 *pwm_reg_an = -pwm1 | 0x4000;
614 * pxmc_rocon_pwm2ph_out - Phase output of the 2-phase stepper motor PWM
615 * @mcs: Motion controller state information
618 pxmc_rocon_pwm2ph_out(pxmc_state_t *mcs)
620 typeof(mcs->pxms_ptvang) ptvang;
628 if(!(mcs->pxms_flg&PXMS_PTI_m) || !(mcs->pxms_flg&PXMS_PHA_m) ||
629 (mcs->pxms_flg&PXMS_PRA_m)){
631 short ptirc=mcs->pxms_ptirc;
634 pxmc_irc_16bit_commindx(mcs, mcs->pxms_rp >> PXMC_SUBDIV(mcs));
639 res = pxmc_inp_rocon_ptofs_from_index_poll(mcs, 0);
641 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
643 pxmc_set_flag(mcs, PXMS_PTI_b);
644 pxmc_set_flag(mcs, PXMS_PHA_b);
649 ptindx = mcs->pxms_ptindx;
651 if(0 && (!(mcs->pxms_flg&PXMS_PTI_m) || (mcs->pxms_flg&PXMS_PRA_m))) {
653 mcs->pxms_ptindx = ptindx;
655 mcs->pxms_ptofs = (mcs->pxms_ap >> PXMC_SUBDIV(mcs)) + mcs->pxms_ptshift - ptindx;
657 pxmc_set_flag(mcs, PXMS_PTI_b);
658 pxmc_clear_flag(mcs, PXMS_PRA_b);
660 /* if phase table position to mask is know do fine phase table alignment */
661 //if(mcs->pxms_cfg & PXMS_CFG_I2PT_m)
662 // lpc_qei_setup_index_catch(&lpc_qei_state);
665 if(!(mcs->pxms_flg&PXMS_PTI_m))
666 mcs->pxms_ptindx = ptindx;
672 /*wind_current[0]=(ADC->ADDR0 & 0xFFF0)>>4;*/
673 /* FIXME - check winding current against limit */
674 /* pxmc_set_errno(mcs, PXMS_E_WINDCURRENT); */
678 ptvang = mcs->pxms_ptvang;
682 ene = mcs->pxms_flg & PXMS_BSY_m? mcs->pxms_me: 0;
686 indx = mcs->pxms_ptindx;
688 /* tuning of magnetic field/voltage advance angle */
689 indx += (mcs->pxms_s1 * mcs->pxms_as) >> (PXMC_SUBDIV(mcs) + 8);
692 /* Generating direction of stator mag. field for backward torque */
694 if ((indx -= ptvang)<0)
695 indx += mcs->pxms_ptirc;
697 /* Generating direction of stator mag. field for forward torque */
698 if ((indx += ptvang) >= mcs->pxms_ptirc)
699 indx -= mcs->pxms_ptirc;
702 if (mcs->pxms_ptscale_mult)
703 indx = ((unsigned long)indx * mcs->pxms_ptscale_mult) >> mcs->pxms_ptscale_shift;
705 pwm1 = mcs->pxms_ptptr1[indx];
706 pwm2 = mcs->pxms_ptptr2[indx];
708 /* Default phase-table amplitude is 0x7fff, ene max is 0x7fff */
709 /* Initialized PWM period is 0x200 => divide by value about 2097024 */
711 unsigned long pwm_dc = pxmc_rocon_pwm_magnitude * (unsigned long)ene;
712 pwm1 = ((unsigned long long)pwm1 * pwm_dc) >> (15+15);
713 pwm2 = ((unsigned long long)pwm2 * pwm_dc) >> (15+15);
715 pxmc_rocon_pwm2ph_wr(mcs, pwm1, pwm2);
717 /*pxmc_lpc_wind_current_over_cnt = 0;*/
718 pxmc_rocon_pwm2ph_wr(mcs, 0, 0);
725 * pxmc_rocon_pwm_dc_out - DC motor CW and CCW PWM output
726 * @mcs: Motion controller state information
729 pxmc_rocon_pwm_dc_out(pxmc_state_t *mcs)
731 volatile uint32_t *pwm_reg_a, *pwm_reg_b;
732 int chan = mcs->pxms_out_info;
733 int ene = mcs->pxms_ene;
735 pwm_reg_a = pxmc_rocon_pwm_chan2reg(chan + 0);
736 pwm_reg_b = pxmc_rocon_pwm_chan2reg(chan + 1);
742 ene = (ene * (pxmc_rocon_pwm_magnitude + 5)) >> 15;
744 *pwm_reg_b = ene | 0x4000;
748 ene = (ene * (pxmc_rocon_pwm_magnitude + 5)) >> 15;
750 *pwm_reg_a = ene | 0x4000;
756 /*******************************************************************/
757 /* PXMCC - PXMC coprocessor support and communication */
759 void pxmcc_pxmc_ptofs2mcc(pxmc_state_t *mcs, int enable_update)
761 volatile pxmcc_axis_data_t *mcc_axis = pxmc_rocon_mcs2pxmcc(mcs);
762 int inp_chan=mcs->pxms_inp_info;
766 if (mcc_axis != NULL) {
767 if (enable_update >= 0)
768 mcc_axis->ptirc = 0xffffffff;
769 ptofs = mcs->pxms_ptofs - pxmc_rocon_irc_offset[inp_chan];
770 irc = fpga_irc[inp_chan]->count;
771 ptofs = (int16_t)(ptofs - irc) + irc;
772 mcc_axis->ptofs = ptofs;
773 if (enable_update > 0) {
774 mcc_axis->ptirc = mcs->pxms_ptirc;
780 void pxmcc_axis_get_cur_dq_filt_raw(pxmc_state_t *mcs,
781 int32_t *p_cur_d_raw, int32_t *p_cur_q_raw)
783 volatile pxmcc_axis_data_t *mcc_axis = pxmc_rocon_mcs2pxmcc(mcs);
784 pxmc_rocon_state_t *mcsrc = pxmc_state2rocon_state(mcs);
785 uint32_t cur_d_cum = mcc_axis->cur_d_cum;
786 uint32_t cur_q_cum = mcc_axis->cur_q_cum;
790 cur_d = cur_d_cum - mcsrc->cur_d_cum_prev;
791 mcsrc->cur_d_cum_prev = cur_d_cum;
792 cur_q = cur_q_cum - mcsrc->cur_q_cum_prev;
793 mcsrc->cur_q_cum_prev = cur_q_cum;
795 *p_cur_d_raw = cur_d;
796 *p_cur_q_raw = cur_q;
800 void pxmcc_axis_cur_dq_raw2filt(int *p_cur, int32_t cur_raw)
804 cur_div = cur_raw & 0x1f;
805 cur = cur_raw / cur_div;
806 cur += (1 << 11) | 0x20;
811 void pxmcc_axis_get_cur_dq_filt(pxmc_state_t *mcs, int *p_cur_d, int *p_cur_q)
816 pxmcc_axis_get_cur_dq_filt_raw(mcs, &cur_d_raw, &cur_q_raw);
818 pxmcc_axis_cur_dq_raw2filt(p_cur_d, cur_d_raw);
819 pxmcc_axis_cur_dq_raw2filt(p_cur_q, cur_q_raw);
823 void pxmcc_cur_ctrl_pi(int *p_pwm, int32_t *p_cur_err_sum,
824 int cur_err, short cur_ctrl_p, short cur_ctrl_i, int max_pwm)
827 int32_t cur_err_sum = *p_cur_err_sum;
829 pwm = (cur_err * cur_ctrl_p) >> 8;
832 cur_err_sum += cur_err * cur_ctrl_i;
836 pwm += cur_err_sum >> 16;
839 cur_err_sum -= (pwm - max_pwm) << 16;
841 } else if (-pwm > max_pwm) {
842 cur_err_sum -= (pwm + max_pwm) << 16;
845 *p_cur_err_sum = cur_err_sum;
850 pxmc_pxmcc_pwm3ph_out(pxmc_state_t *mcs)
854 pxmc_rocon_state_t *mcsrc = pxmc_state2rocon_state(mcs);
856 if (!(mcs->pxms_flg & PXMS_PTI_m) || !(mcs->pxms_flg & PXMS_PHA_m) ||
857 (mcs->pxms_flg & PXMS_PRA_m)) {
859 short ptirc = mcs->pxms_ptirc;
860 short divisor = mcs->pxms_ptper * 6;
861 unsigned char hal_pos;
863 hal_pos = pxmc_lpc_bdc_hal_pos_table[pxmc_rocon_bldc_hal_rd(mcs)];
865 if (hal_pos == 0xff) {
867 pxmc_rocon_process_hal_error(mcs);
869 if (mcs->pxms_halerc)
872 ptindx = (hal_pos * ptirc + divisor / 2) / divisor;
874 if (!(mcs->pxms_flg & PXMS_PTI_m) || (mcs->pxms_flg & PXMS_PRA_m)) {
875 int set_ptofs_fl = 0;
876 int ptofs_enable_update = 0;
878 if (((hal_pos != mcs->pxms_hal) && (mcs->pxms_hal != 0x40)) && 1) {
879 short ptindx_prev = (mcs->pxms_hal * ptirc + divisor / 2) / divisor;;
881 if ((ptindx > ptindx_prev + ptirc / 2) ||
882 (ptindx_prev > ptindx + ptirc / 2)) {
883 ptindx = (ptindx_prev + ptindx - ptirc) / 2;
888 ptindx = (ptindx_prev + ptindx) / 2;
892 ptofs_enable_update = 1;
894 pxmc_set_flag(mcs, PXMS_PTI_b);
895 pxmc_clear_flag(mcs, PXMS_PRA_b);
897 if (!(mcs->pxms_flg & PXMS_PTI_m))
901 mcs->pxms_ptindx = ptindx;
902 mcs->pxms_ptofs = (mcs->pxms_ap >> PXMC_SUBDIV(mcs)) + mcs->pxms_ptshift - ptindx;
904 pxmcc_pxmc_ptofs2mcc(mcs, ptofs_enable_update);
907 /* if phase table position to mask is know do fine phase table alignment */
908 if (mcs->pxms_cfg & PXMS_CFG_I2PT_m) {
911 res = pxmc_inp_rocon_ptofs_from_index_poll(mcs, 0);
913 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
915 pxmcc_pxmc_ptofs2mcc(mcs, 1);
916 pxmc_set_flag(mcs, PXMS_PTI_b);
917 pxmc_set_flag(mcs, PXMS_PHA_b);
921 mcs->pxms_hal = hal_pos;
925 pxmcc_axis_get_cur_dq_filt_raw(mcs, &cur_d_raw, &cur_q_raw);
928 /*wind_current[0]=(ADC->ADDR0 & 0xFFF0)>>4;*/
929 /* FIXME - check winding current against limit */
930 /* pxmc_set_errno(mcs, PXMS_E_WINDCURRENT); */
934 int ene, pwm_d, pwm_q;
938 pwm_q = (pxmc_rocon_pwm_magnitude * ene) >> 15;
940 if (mcs->pxms_flg & (PXMS_ENR_m | PXMS_ENO_m)) {
942 int cur_d_req, cur_d_err;
943 int max_pwm = (pxmc_rocon_pwm_magnitude * mcs->pxms_me) >> 15;
947 pxmcc_axis_cur_dq_raw2filt(&cur_d, cur_d_raw);
949 cur_d_err = cur_d_req - cur_d;
951 pxmcc_cur_ctrl_pi(&pwm_d, &mcsrc->cur_d_err_sum, cur_d_err,
952 mcsrc->cur_d_p, mcsrc->cur_d_i, max_pwm);
955 pxmcc_axis_pwm_dq_out(mcs, pwm_d, pwm_q);
957 if (mcs->pxms_flg & PXMS_ERR_m)
958 pxmc_rocon_pwm3ph_wr(mcs, 0, 0, 0);
965 pxmc_pxmcc_pwm2ph_out(pxmc_state_t *mcs)
967 pxmc_rocon_state_t *mcsrc = pxmc_state2rocon_state(mcs);
971 pxmcc_axis_get_cur_dq_filt_raw(mcs, &cur_d_raw, &cur_q_raw);
973 if(!(mcs->pxms_flg&PXMS_PTI_m) || !(mcs->pxms_flg&PXMS_PHA_m) ||
974 (mcs->pxms_flg&PXMS_PRA_m)) {
977 /* Wait for index mark to align phases */
979 res = pxmc_inp_rocon_ptofs_from_index_poll(mcs, 0);
981 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
983 pxmcc_pxmc_ptofs2mcc(mcs, 1);
984 pxmc_set_flag(mcs, PXMS_PTI_b);
985 pxmc_set_flag(mcs, PXMS_PHA_b);
987 pxmcc_pxmc_ptofs2mcc(mcs, 0);
993 int ene, pwm_d, pwm_q;
998 if (mcs->pxms_flg & PXMS_PHA_m &&
999 (mcs->pxms_flg & (PXMS_ENR_m | PXMS_ENO_m))) {
1001 int cur_d_req, cur_d_err;
1002 int max_pwm = (pxmc_rocon_pwm_magnitude * mcs->pxms_me) >> 15;
1006 pxmcc_axis_cur_dq_raw2filt(&cur_d, cur_d_raw);
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);
1014 pwm_q = (pxmc_rocon_pwm_magnitude * ene) >> 15;
1016 pxmcc_axis_pwm_dq_out(mcs, pwm_d, pwm_q);
1018 if (mcs->pxms_flg & PXMS_ERR_m)
1019 pxmc_rocon_pwm2ph_wr(mcs, 0, 0);
1026 * pxmc_pxmcc_nofb_inp - Dummy input for direct stepper motor control
1027 * @mcs: Motion controller state information
1030 pxmc_pxmcc_nofb_inp(pxmc_state_t *mcs)
1036 * pxmc_pxmcc_nofb_con - Empty controller for direct stepper motor control
1037 * @mcs: Motion controller state information
1040 pxmc_pxmcc_nofb_con(pxmc_state_t *mcs)
1042 mcs->pxms_ene=mcs->pxms_me;
1047 pxmc_pxmcc_nofb2ph_out(pxmc_state_t *mcs)
1049 pxmc_rocon_state_t *mcsrc = pxmc_state2rocon_state(mcs);
1050 volatile pxmcc_axis_data_t *mcc_axis = pxmc_rocon_mcs2pxmcc(mcs);
1054 pxmcc_axis_get_cur_dq_filt_raw(mcs, &cur_d_raw, &cur_q_raw);
1056 if ((mcs->pxms_flg & PXMS_ERR_m) ||
1057 !(mcs->pxms_flg & (PXMS_ENO_m | PXMS_ENR_m))) {
1058 pxmc_rocon_pwm2ph_wr(mcs, 0, 0);
1059 pxmcc_axis_pwm_dq_out(mcs, 0, 0);
1060 mcc_axis->steps_inc = 0;
1061 mcsrc->cur_d_err_sum = 0;
1062 mcsrc->cur_q_err_sum = 0;
1066 int cur_d_req, cur_d_err;
1067 int cur_q_req, cur_q_err;
1068 int max_pwm = mcs->pxms_me;
1071 pxmcc_axis_cur_dq_raw2filt(&cur_d, cur_d_raw);
1072 pxmcc_axis_cur_dq_raw2filt(&cur_q, cur_q_raw);
1077 cur_d_req = mcsrc->cur_hold;
1079 cur_d_err = cur_d_req - cur_d;
1081 pxmcc_cur_ctrl_pi(&pwm_d, &mcsrc->cur_d_err_sum, cur_d_err,
1082 mcsrc->cur_d_p, mcsrc->cur_d_i, max_pwm);
1084 /* pwm_d = (pxmc_rocon_pwm_magnitude * ene) >> 15; */
1088 cur_q_err = cur_q_req - cur_q;
1090 pxmcc_cur_ctrl_pi(&pwm_q, &mcsrc->cur_q_err_sum, cur_q_err,
1091 mcsrc->cur_q_p, mcsrc->cur_q_i, max_pwm);
1093 pxmcc_axis_pwm_dq_out(mcs, pwm_d, pwm_q);
1095 mcs->pxms_ap=mcs->pxms_rp;
1096 mcs->pxms_as=mcs->pxms_rs;
1097 mcc_axis->steps_lim = mcc_axis->steps_cnt + 6;
1099 stpinc = mcs->pxms_rs;
1100 mcc_axis->steps_inc = stpinc;
1102 /* stpinc /= (mcs->pxms_ptirc << PXMC_SUBDIV(mcs)); */
1103 /* pxms_ptscale_mult; pxms_ptscale_shift; */
1109 int pxmcc_axis_setup(pxmc_state_t *mcs, int mode)
1111 volatile pxmcc_data_t *mcc_data = pxmc_rocon_mcc_data();
1112 volatile pxmcc_axis_data_t *mcc_axis = pxmc_rocon_mcs2pxmcc(mcs);
1116 uint32_t pwmtx_info;
1117 uint32_t pwmtx_info_dummy = 27;
1123 if (mcc_axis == NULL)
1126 if (mcc_data->common.fwversion != PXMCC_FWVERSION)
1129 mcc_axis->ccflg = 0;
1130 mcc_axis->mode = PXMCC_MODE_IDLE;
1132 mcc_data->common.pwm_cycle = PXMC_LXPWR_PWM_CYCLE;
1134 ptirc = mcs->pxms_ptirc;
1135 ull = (1ULL << 32) * mcs->pxms_ptper;
1136 ptreci = (ull + ptirc / 2) / ptirc;
1138 mcc_axis->ptreci = ptreci;
1140 pxmcc_pxmc_ptofs2mcc(mcs, 0);
1142 inp_info = (char*)&fpga_irc[mcs->pxms_inp_info]->count - (char*)fpga_irc[0];
1143 inp_info += mcc_data->common.irc_base;
1146 case PXMCC_MODE_IDLE:
1149 case PXMCC_MODE_BLDC:
1152 case PXMCC_MODE_STEPPER_WITH_IRC:
1155 case PXMCC_MODE_STEPPER:
1157 mcc_axis->ptreci = 1;
1158 inp_info = (char*)&mcc_axis->steps_pos - (char*)mcc_data;
1162 mcc_axis->inp_info = inp_info;
1163 mcc_axis->out_info = mcs->pxms_out_info;
1165 pwm_chan = mcs->pxms_out_info;
1167 pwmtx_info = (pwmtx_info_dummy << 0) | (pwmtx_info_dummy << 8) |
1168 (pwmtx_info_dummy << 16) | (pwmtx_info_dummy << 24);
1170 for (i = phcnt; --i >= 0; ) {
1171 volatile uint32_t *pwm_reg;
1172 volatile uint32_t *pwm_reg_base = fpga_lx_master_transmitter_base;
1176 pwm_reg = pxmc_rocon_pwm_chan2reg(pwm_chan + i);
1177 if (pwm_reg == &pxmc_rocon_pwm_dummy_reg) {
1178 pwmtx_info |= pwmtx_info_dummy;
1180 pwmtx_info |= pwm_reg - pwm_reg_base;
1184 mcc_axis->pwmtx_info = pwmtx_info;
1186 mcc_axis->mode = mode;
1188 mcc_axis->ccflg = 0;
1189 mcc_axis->pwm_dq = 0;
1190 mcc_axis->steps_lim = mcc_axis->steps_cnt;
1191 mcc_axis->steps_inc = 0;
1192 mcc_axis->steps_pos = 0;
1194 if (mode != PXMCC_MODE_STEPPER) {
1195 pxmcc_pxmc_ptofs2mcc(mcs, 1);
1200 /*******************************************************************/
1202 volatile void *pxmc_rocon_rx_data_hist_buff;
1203 volatile void *pxmc_rocon_rx_data_hist_buff_end;
1204 int pxmc_rocon_rx_data_hist_mode;
1206 uint32_t pxmc_rocon_rx_last_irq;
1207 uint32_t pxmc_rocon_rx_cycle_time;
1208 uint32_t pxmc_rocon_rx_irq_latency;
1209 uint32_t pxmc_rocon_rx_irq_latency_max;
1211 IRQ_HANDLER_FNC(pxmc_rocon_rx_done_isr)
1215 ir = ROCON_RX_TIM->IR & LPC_TIM_IR_ALL_m;
1216 ROCON_RX_TIM->IR = ir;
1217 if (ir & LPC_TIM_IR_CR1INT_m) {
1219 cr0 = ROCON_RX_TIM->CR0;
1220 cr1 = ROCON_RX_TIM->CR1;
1222 pxmc_rocon_rx_cycle_time = cr1 - pxmc_rocon_rx_last_irq;
1223 pxmc_rocon_rx_last_irq = cr1;
1225 hal_gpio_set_value(T2MAT0_PIN, 1);
1226 hal_gpio_set_value(T2MAT1_PIN, 0);
1227 hal_gpio_set_value(T2MAT0_PIN, 0);
1229 pxmc_rocon_vin_compute();
1231 if (pxmc_rocon_rx_data_hist_buff >= pxmc_rocon_rx_data_hist_buff_end)
1232 pxmc_rocon_rx_data_hist_buff = NULL;
1234 if (pxmc_rocon_rx_data_hist_buff != NULL) {
1235 if (pxmc_rocon_rx_data_hist_mode == 0) {
1237 volatile uint32_t *pwm_reg = fpga_lx_master_transmitter_base + 8;
1238 volatile uint32_t *rec_reg = fpga_lx_master_receiver_base + 8;
1239 uint16_t *pbuf = (uint16_t *)pxmc_rocon_rx_data_hist_buff;
1240 for (i = 0; i < 8; i++) {
1241 *(pbuf++) = *(rec_reg++);
1243 for (i = 0; i < 8; i++) {
1244 *(pbuf++) = *(pwm_reg++);
1246 pxmc_rocon_rx_data_hist_buff = pbuf;
1247 } else if (pxmc_rocon_rx_data_hist_mode == 1) {
1249 uint32_t *pbuf = (uint32_t *)pxmc_rocon_rx_data_hist_buff;
1250 pxmcc_data_t *mcc_data = pxmc_rocon_mcc_data();
1251 pxmcc_axis_data_t *mcc_axis = mcc_data->axis + 0;
1252 uint32_t *ptumbl = (uint32_t *)mcc_axis;
1254 for (i = 0; i < 16; i++)
1255 *(pbuf++) = *(ptumbl++);
1257 pxmc_rocon_rx_data_hist_buff = pbuf;
1261 pxmc_rocon_rx_irq_latency = ROCON_RX_TIM->TC - cr1;
1262 if (pxmc_rocon_rx_irq_latency > pxmc_rocon_rx_irq_latency_max)
1263 pxmc_rocon_rx_irq_latency_max = pxmc_rocon_rx_irq_latency;
1265 #ifdef PXMC_ROCON_TIMED_BY_RX_DONE
1268 #endif /*PXMC_ROCON_TIMED_BY_RX_DONE*/
1275 pxmc_rocon_rx_done_isr_setup(irq_handler_t rx_done_isr_handler)
1278 disable_irq(ROCON_RX_IRQn);
1280 hal_pin_conf_set(T2MAT0_PIN, PORT_CONF_GPIO_OUT_LO);
1281 hal_pin_conf_set(T2MAT1_PIN, PORT_CONF_GPIO_OUT_LO);
1282 hal_pin_conf(T2CAP0_PIN);
1283 hal_pin_conf(T2CAP1_PIN);
1285 hal_gpio_direction_output(T2MAT0_PIN, 1);
1286 hal_gpio_direction_output(T2MAT1_PIN, 0);
1287 hal_gpio_set_value(T2MAT0_PIN, 0);
1289 /* Enable CLKOUT pin function, source CCLK, divide by 1 */
1290 LPC_SC->CLKOUTCFG = 0x0100;
1292 request_irq(ROCON_RX_IRQn, rx_done_isr_handler, 0, NULL,NULL);
1294 ROCON_RX_TIM->TCR = 0;
1295 ROCON_RX_TIM->CTCR = 0;
1296 ROCON_RX_TIM->PR = 0; /* Divide by 1 */
1298 ROCON_RX_TIM->CCR = LPC_TIM_CCR_CAP0RE_m | LPC_TIM_CCR_CAP1FE_m |
1299 LPC_TIM_CCR_CAP1I_m;
1301 ROCON_RX_TIM->EMR = __val2mfld(LPC_TIM_EMR_EMC0_m, LPC_TIM_EMR_NOP) |
1302 __val2mfld(LPC_TIM_EMR_EMC1_m, LPC_TIM_EMR_NOP);
1304 ROCON_RX_TIM->MCR = 0; /* No IRQ on MRx */
1305 ROCON_RX_TIM->TCR = LPC_TIM_TCR_CEN_m; /* Enable timer counting */
1306 enable_irq(ROCON_RX_IRQn); /* Enable interrupt */
1313 pxmc_rocon_pwm_master_init(void)
1319 unsigned receiver_done_div = 1;
1320 #ifdef LXPWR_WITH_SIROLADC
1321 unsigned lxpwr_header = 1;
1322 unsigned lxpwr_words = 1 + 8 * 2 + 2;
1323 unsigned lxpwr_chips = 2;
1324 unsigned lxpwr_chip_pwm_cnt = 8;
1325 #else /*LXPWR_WITH_SIROLADC*/
1326 unsigned lxpwr_header = 0;
1327 unsigned lxpwr_words = 8;
1328 unsigned lxpwr_chips = 2;
1329 unsigned lxpwr_chip_pwm_cnt = 8;
1330 #endif /*LXPWR_WITH_SIROLADC*/
1332 #ifdef PXMC_ROCON_TIMED_BY_RX_DONE
1333 receiver_done_div = 5;
1334 #endif /*PXMC_ROCON_TIMED_BY_RX_DONE*/
1336 *fpga_lx_master_reset = 1;
1337 *fpga_lx_master_transmitter_reg = 0;
1338 *fpga_lx_master_transmitter_cycle = PXMC_LXPWR_PWM_CYCLE; /* 50 MHz -> 20 kHz */
1339 *fpga_lx_master_receiver_done_div = receiver_done_div << 8;
1341 for (i = 0; i < LX_MASTER_DATA_OFFS + lxpwr_words * lxpwr_chips; i++)
1342 fpga_lx_master_receiver_base[i] = 0;
1344 word_slot = LX_MASTER_DATA_OFFS;
1345 fpga_lx_master_receiver_base[grp_in++] = (word_slot << 8) | lxpwr_words;
1346 fpga_lx_master_receiver_base[grp_in++] = 0x0000;
1348 for (i = 0; i < LX_MASTER_DATA_OFFS + lxpwr_words * lxpwr_chips; i++)
1349 fpga_lx_master_transmitter_base[i] = 0;
1351 word_slot = LX_MASTER_DATA_OFFS + lxpwr_header + lxpwr_chip_pwm_cnt;
1352 fpga_lx_master_transmitter_base[grp_out++] = (word_slot << 8) | lxpwr_words;
1353 #ifdef LXPWR_WITH_SIROLADC
1354 fpga_lx_master_transmitter_base[word_slot] = 0xc100 | (lxpwr_words - 1);
1355 #endif /*LXPWR_WITH_SIROLADC*/
1357 word_slot = LX_MASTER_DATA_OFFS + 0;
1358 fpga_lx_master_transmitter_base[grp_out++] = (word_slot << 8) | lxpwr_words;
1359 #ifdef LXPWR_WITH_SIROLADC
1360 fpga_lx_master_transmitter_base[word_slot] = 0xc100 | (lxpwr_words - 1);
1361 #endif /*LXPWR_WITH_SIROLADC*/
1363 fpga_lx_master_transmitter_base[grp_out++] = 0x0000;
1365 *fpga_lx_master_reset = 0;
1366 *fpga_lx_master_transmitter_cycle = PXMC_LXPWR_PWM_CYCLE; /* 50 MHz -> 20 kHz */
1367 *fpga_lx_master_receiver_done_div = receiver_done_div << 8;
1372 int pxmc_ptofs_from_index(pxmc_state_t *mcs, unsigned long irc,
1373 unsigned long index_irc, int diff2err)
1378 ofs = ofsl = index_irc - mcs->pxms_ptmark;
1382 diff = (unsigned short)ofs - (unsigned short)mcs->pxms_ptofs;
1383 if (diff >= mcs->pxms_ptirc / 2)
1384 diff -= mcs->pxms_ptirc;
1385 if (diff <= -mcs->pxms_ptirc / 2)
1386 diff += mcs->pxms_ptirc;
1389 if(diff >= mcs->pxms_ptirc / 6) {
1394 diff = (unsigned long)ofsl - irc;
1395 ofs = ofsl - (diff / mcs->pxms_ptirc) * mcs->pxms_ptirc;
1398 mcs->pxms_ptofs = ofs;
1404 * pxmc_dummy_con - Dummy controller for synchronous BLDC/PMSM/steper drive
1405 * @mcs: Motion controller state information
1408 pxmc_dummy_con(pxmc_state_t *mcs)
1413 int pxmc_rocon_hh_gd10(pxmc_state_t *mcs);
1414 int pxmc_rocon_hh_gd20(pxmc_state_t *mcs);
1415 int pxmc_rocon_hh_gd30(pxmc_state_t *mcs);
1416 int pxmc_rocon_hh_gd40(pxmc_state_t *mcs);
1417 int pxmc_rocon_hh_gd50(pxmc_state_t *mcs);
1418 int pxmc_rocon_hh_gd90(pxmc_state_t *mcs);
1420 /* initialize for hard home */
1422 pxmc_rocon_hh_gi(pxmc_state_t *mcs)
1424 pxmc_set_flag(mcs,PXMS_BSY_b);
1425 #if 0 /* config and speed already set in pxmc_hh */
1427 spd >>= mcs->pxms_cfg & PXMS_CFG_HSPD_m;
1429 if(mcs->pxms_cfg & PXMS_CFG_HDIR_m)
1431 mcs->pxms_gen_hsp = spd;
1434 mcs->pxms_gen_htim = 16;
1435 mcs->pxms_do_gen = pxmc_rocon_hh_gd10;
1436 return pxmc_rocon_hh_gd10(mcs);
1439 /* fill initial mark filter and then decide */
1441 pxmc_rocon_hh_gd10(pxmc_state_t *mcs)
1445 if(mcs->pxms_flg & PXMS_ERR_m)
1446 return pxmc_spdnext_gend(mcs);
1448 pxmc_spd_gacc(&(mcs->pxms_rs), 0, mcs->pxms_ma);
1449 mcs->pxms_rp += mcs->pxms_rs;
1451 mark = pxmc_inp_rocon_is_mark(mcs);
1453 if (mcs->pxms_gen_htim) {
1454 mcs->pxms_gen_htim--;
1458 if (!(mcs->pxms_cfg & PXMS_CFG_HLS_m)) {
1459 /* limit switch is not used */
1460 pxmc_inp_rocon_is_index_edge(mcs);
1461 mcs->pxms_do_gen = pxmc_rocon_hh_gd50;
1466 /* go out from switch */
1467 mcs->pxms_do_gen = pxmc_rocon_hh_gd20;
1469 /* switch is off -> look for it */
1470 mcs->pxms_do_gen = pxmc_rocon_hh_gd30;
1475 /* go out from switch */
1477 pxmc_rocon_hh_gd20(pxmc_state_t *mcs)
1481 if(mcs->pxms_flg & PXMS_ERR_m)
1482 return pxmc_spdnext_gend(mcs);
1484 mark = pxmc_inp_rocon_is_mark(mcs);
1487 /* switch is off -> look for it again */
1488 mcs->pxms_do_gen = pxmc_rocon_hh_gd30;
1491 pxmc_spd_gacc(&(mcs->pxms_rs), -mcs->pxms_gen_hsp, mcs->pxms_ma);
1492 mcs->pxms_rp += mcs->pxms_rs;
1497 /* switch is off -> look for it */
1499 pxmc_rocon_hh_gd30(pxmc_state_t *mcs)
1504 if (mcs->pxms_flg & PXMS_ERR_m)
1505 return pxmc_spdnext_gend(mcs);
1507 pxmc_spd_gacc(&(mcs->pxms_rs), mcs->pxms_gen_hsp, mcs->pxms_ma);
1508 mcs->pxms_rp += mcs->pxms_rs;
1510 mark = pxmc_inp_rocon_is_mark(mcs);
1513 spd = mcs->pxms_gen_hsp >> 2; /* slow down */
1516 mcs->pxms_gen_hsp = spd;
1517 mcs->pxms_do_gen = pxmc_rocon_hh_gd40;
1523 /* switch is on -> find edge */
1525 pxmc_rocon_hh_gd40(pxmc_state_t *mcs)
1529 if (mcs->pxms_flg & PXMS_ERR_m)
1530 return pxmc_spdnext_gend(mcs);
1532 mark = pxmc_inp_rocon_is_mark(mcs);
1535 if (mcs->pxms_cfg & PXMS_CFG_HRI_m) {
1536 pxmc_inp_rocon_is_index_edge(mcs);
1537 mcs->pxms_do_gen = pxmc_rocon_hh_gd50;
1539 pxmc_inp_rocon_ap_zero(mcs);
1540 mcs->pxms_do_gen = pxmc_stop_gi;
1544 pxmc_spd_gacc(&(mcs->pxms_rs), -mcs->pxms_gen_hsp, mcs->pxms_ma);
1545 mcs->pxms_rp += mcs->pxms_rs;
1550 /* calibrate on revolution index */
1552 pxmc_rocon_hh_gd50(pxmc_state_t *mcs)
1554 if (mcs->pxms_flg & PXMS_ERR_m)
1555 return pxmc_spdnext_gend(mcs);
1557 pxmc_spd_gacc(&(mcs->pxms_rs), mcs->pxms_gen_hsp, mcs->pxms_ma);
1558 mcs->pxms_rp += mcs->pxms_rs;
1560 if (pxmc_inp_rocon_is_index_edge(mcs)){
1561 pxmc_inp_rocon_irc_offset_from_index(mcs);
1562 mcs->pxms_do_gen = pxmc_stop_gi;
1568 pxmc_call_t *pxmc_get_hh_gi_4axis(pxmc_state_t *mcs)
1570 return pxmc_rocon_hh_gi;
1573 pxmc_rocon_state_t mcs0 =
1581 pxmc_pid_con /*pxmc_dummy_con*/,
1583 pxmc_rocon_pwm_dc_out /*pxmc_rocon_pwm3ph_out*/,
1587 pxmc_inp_rocon_ap2hw,
1588 pxms_ap: 0, pxms_as: 0,
1589 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1590 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
1593 pxms_ene: 0, pxms_erc: 0,
1594 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1595 pxms_me: 0x7e00/*0x7fff*/,
1597 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m * 0 |
1598 PXMS_CFG_HRI_m * 0 | PXMS_CFG_HDIR_m * 0 |
1599 PXMS_CFG_I2PT_m * 0 | 0x2,
1604 /*pxms_ptamp: 0x7fff,*/
1615 pxmc_rocon_state_t mcs1 =
1625 pxmc_rocon_pwm_dc_out,
1629 pxmc_inp_rocon_ap2hw,
1630 pxms_ap: 0, pxms_as: 0,
1631 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1632 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
1635 pxms_ene: 0, pxms_erc: 0,
1636 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1637 pxms_me: 0x7e00/*0x7fff*/,
1639 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m * 0 |
1640 PXMS_CFG_HRI_m * 0 | PXMS_CFG_HDIR_m * 0 |
1641 PXMS_CFG_I2PT_m * 0 | 0x2,
1645 /*pxms_ptamp: 0x7fff,*/
1650 pxmc_rocon_state_t mcs2 =
1660 pxmc_rocon_pwm_dc_out,
1664 pxmc_inp_rocon_ap2hw,
1665 pxms_ap: 0, pxms_as: 0,
1666 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1667 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
1670 pxms_ene: 0, pxms_erc: 0,
1671 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1672 pxms_me: 0x7e00/*0x7fff*/,
1674 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m * 0 |
1675 PXMS_CFG_I2PT_m * 0 | PXMS_CFG_HRI_m |
1676 PXMS_CFG_HDIR_m | 0x2,
1680 /*pxms_ptamp: 0x7fff,*/
1685 pxmc_rocon_state_t mcs3 =
1695 pxmc_rocon_pwm_dc_out,
1699 pxmc_inp_rocon_ap2hw,
1700 pxms_ap: 0, pxms_as: 0,
1701 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1702 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
1705 pxms_ene: 0, pxms_erc: 0,
1706 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1707 pxms_me: 0x7e00/*0x7fff*/,
1709 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m * 0 |
1710 PXMS_CFG_I2PT_m * 0 | PXMS_CFG_HRI_m |
1711 PXMS_CFG_HDIR_m * 0 | 0x2,
1715 /*pxms_ptamp: 0x7fff,*/
1720 pxmc_rocon_state_t mcs4 =
1730 pxmc_rocon_pwm_dc_out,
1734 pxmc_inp_rocon_ap2hw,
1735 pxms_ap: 0, pxms_as: 0,
1736 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1737 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
1740 pxms_ene: 0, pxms_erc: 0,
1741 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1742 pxms_me: 0x7e00/*0x7fff*/,
1744 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m * 0 |
1745 PXMS_CFG_HRI_m | PXMS_CFG_I2PT_m * 0 |
1746 PXMS_CFG_HDIR_m | 0x2,
1750 /*pxms_ptamp: 0x7fff,*/
1755 pxmc_rocon_state_t mcs5 =
1765 pxmc_rocon_pwm_dc_out,
1769 pxmc_inp_rocon_ap2hw,
1770 pxms_ap: 0, pxms_as: 0,
1771 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1772 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
1775 pxms_ene: 0, pxms_erc: 0,
1776 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1777 pxms_me: 0x7e00/*0x7fff*/,
1779 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m |
1780 PXMS_CFG_HRI_m | PXMS_CFG_I2PT_m * 0 |
1781 PXMS_CFG_HDIR_m | 0x2,
1785 /*pxms_ptamp: 0x7fff,*/
1790 pxmc_rocon_state_t mcs6 =
1800 pxmc_rocon_pwm_dc_out,
1804 pxmc_inp_rocon_ap2hw,
1805 pxms_ap: 0, pxms_as: 0,
1806 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1807 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
1810 pxms_ene: 0, pxms_erc: 0,
1811 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1812 pxms_me: 0x7e00/*0x7fff*/,
1814 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_I2PT_m * 0 |
1819 /*pxms_ptamp: 0x7fff,*/
1824 pxmc_rocon_state_t mcs7 =
1834 pxmc_rocon_pwm_dc_out,
1838 pxmc_inp_rocon_ap2hw,
1839 pxms_ap: 0, pxms_as: 0,
1840 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1841 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
1844 pxms_ene: 0, pxms_erc: 0,
1845 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1846 pxms_me: 0x7e00/*0x7fff*/,
1848 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_I2PT_m * 0 |
1853 /*pxms_ptamp: 0x7fff,*/
1858 pxmc_state_t *pxmc_main_arr[PXML_MAIN_CNT] =
1859 {&mcs0.base, &mcs1.base, &mcs2.base, &mcs3.base,
1860 &mcs4.base, &mcs5.base, &mcs6.base, &mcs7.base};
1863 pxmc_state_list_t pxmc_main_list =
1870 void pxmc_lpc_qei_callback_index(struct lpc_qei_state_t *qst, void *context)
1872 pxmc_state_t *mcs = (pxmc_state_t *)context;
1875 irc = qst->index_pos;
1877 if ((mcs->pxms_cfg & PXMS_CFG_I2PT_m) && (mcs->pxms_flg & PXMS_PTI_m))
1880 ofs = irc - mcs->pxms_ptmark;
1881 diff = ofs - mcs->pxms_ptofs;
1883 if (diff >= mcs->pxms_ptirc / 2)
1884 diff -= mcs->pxms_ptirc;
1886 if (diff <= -mcs->pxms_ptirc / 2)
1887 diff += mcs->pxms_ptirc;
1892 if (diff >= mcs->pxms_ptirc / 6)
1894 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
1898 mcs->pxms_ptofs = ofs;
1899 pxmc_set_flag(mcs, PXMS_PHA_b);
1903 ofs=irc-mcs->pxms_ptofs;
1904 if((unsigned short)ofs>=(unsigned short)mcs->pxms_ptirc) {
1906 ofs-=mcs->pxms_ptirc;
1908 ofs+=mcs->pxms_ptirc;
1911 mcs->pxms_ptmark=ofs;
1914 /*lpc_qei_set_cmpos(qst, 0, qst->index_pos-4000);*/
1917 int pxmc_lpc_pthalalign_callback(pxmc_state_t *mcs)
1921 lpc_qei_state_t *qst = &lpc_qei_state;
1922 int irc = lpc_qei_get_pos(qst);
1925 if (!qst->index_occ)
1928 idx_rel = qst->index_pos - irc;
1929 idx_rel %= mcs->pxms_ptirc;
1932 idx_rel += mcs->pxms_ptirc;
1934 ptofs = irc - mcs->pxms_ptofs;
1935 ptmark = ptofs + idx_rel;
1937 if ((unsigned short)ptmark >= mcs->pxms_ptirc)
1940 ptmark -= mcs->pxms_ptirc;
1942 ptmark += mcs->pxms_ptirc;
1945 if ((unsigned short)ptmark < mcs->pxms_ptirc)
1947 mcs->pxms_ptmark = ptmark;
1953 int pxmc_lpc_pthalalign(pxmc_state_t *mcs, int periods)
1958 pxmc_call_t *fin_fnc = pxmc_lpc_pthalalign_callback;
1959 lpc_qei_state_t *qst = &lpc_qei_state;
1961 mcs->pxms_cfg &= ~PXMS_CFG_I2PT_m;
1962 lpc_qei_setup_index_catch(qst);
1964 r2acq = ((long)mcs->pxms_ptirc << PXMC_SUBDIV(mcs)) * periods;
1965 spd = 1 << PXMC_SUBDIV(mcs);
1967 res = pxmc_pthalalign(mcs, r2acq, spd, fin_fnc);
1972 int pxmc_lpc_pthalalign_run(void)
1974 return pxmc_lpc_pthalalign(pxmc_main_list.pxml_arr[0], 20);
1977 static inline void pxmc_sfi_input(void)
1981 pxmc_for_each_mcs(var, mcs)
1983 /* PXMS_ENI_m - check if input (IRC) update is enabled */
1984 if (mcs->pxms_flg & PXMS_ENI_m)
1986 pxmc_call(mcs, mcs->pxms_do_inp);
1991 static inline void pxmc_sfi_controller_and_output(void)
1995 pxmc_for_each_mcs(var, mcs)
1997 /* PXMS_ENR_m - check if controller is enabled */
1998 if (mcs->pxms_flg & PXMS_ENR_m || mcs->pxms_flg & PXMS_ENO_m)
2001 /* If output only is enabled, we skip the controller */
2002 if (mcs->pxms_flg & PXMS_ENR_m)
2005 pxmc_call(mcs, mcs->pxms_do_con);
2007 /* PXMS_ERR_m - if axis in error state */
2008 if (mcs->pxms_flg & PXMS_ERR_m)
2012 /* for bushless motors, it is necessary to call do_out
2013 even if the controller is not enabled and PWM should be provided. */
2014 pxmc_call(mcs, mcs->pxms_do_out);
2019 static inline void pxmc_sfi_generator(void)
2023 pxmc_for_each_mcs(var, mcs)
2025 /* PXMS_ENG_m - check if requested value (position) generator is enabled */
2026 if (mcs->pxms_flg & PXMS_ENG_m)
2028 pxmc_call(mcs, mcs->pxms_do_gen);
2033 static inline void pxmc_sfi_dbg(void)
2037 pxmc_for_each_mcs(var, mcs)
2039 if (mcs->pxms_flg & PXMS_DBG_m)
2041 pxmc_call(mcs, mcs->pxms_do_deb);
2046 int pxmc_rocon_pthalalign_callback(pxmc_state_t *mcs)
2050 int inp_chan = mcs->pxms_inp_info;
2052 long irc = fpga_irc[inp_chan]->count;
2054 if (!pxmc_inp_rocon_is_index_edge(mcs))
2057 idx_rel = fpga_irc[inp_chan]->count_index - irc;
2058 idx_rel %= mcs->pxms_ptirc;
2060 idx_rel += mcs->pxms_ptirc;
2062 ptofs = irc-mcs->pxms_ptofs;
2063 ptmark = ptofs+idx_rel;
2065 if((unsigned short)ptmark >= mcs->pxms_ptirc) {
2067 ptmark -= mcs->pxms_ptirc;
2069 ptmark += mcs->pxms_ptirc;
2072 if((unsigned short)ptmark < mcs->pxms_ptirc) {
2073 mcs->pxms_ptmark = ptmark;
2078 int pxmc_rocon_pthalalign(pxmc_state_t *mcs, int periods)
2083 pxmc_call_t *fin_fnc = pxmc_rocon_pthalalign_callback;
2085 mcs->pxms_cfg&=~PXMS_CFG_I2PT_m;
2087 r2acq=((long)mcs->pxms_ptirc<<PXMC_SUBDIV(mcs))*periods;
2088 spd=1<<PXMC_SUBDIV(mcs);
2090 /* clear bit indicating previous index */
2091 pxmc_inp_rocon_is_index_edge(mcs);
2093 res=pxmc_pthalalign(mcs, r2acq, spd, fin_fnc);
2098 int pxmc_axis_rdmode(pxmc_state_t *mcs)
2100 if (mcs->pxms_do_out == pxmc_rocon_pwm2ph_out)
2101 return PXMC_AXIS_MODE_STEPPER_WITH_IRC;
2102 if (mcs->pxms_do_out == pxmc_rocon_pwm_dc_out)
2103 return PXMC_AXIS_MODE_DC;
2104 if (mcs->pxms_do_out == pxmc_rocon_pwm3ph_out)
2105 return PXMC_AXIS_MODE_BLDC;
2106 if (mcs->pxms_do_out == pxmc_pxmcc_pwm3ph_out)
2107 return PXMC_AXIS_MODE_BLDC_PXMCC;
2108 if (mcs->pxms_do_out == pxmc_pxmcc_pwm2ph_out)
2109 return PXMC_AXIS_MODE_STEPPER_WITH_IRC_PXMCC;
2110 if (mcs->pxms_do_out == pxmc_pxmcc_nofb2ph_out)
2111 return PXMC_AXIS_MODE_STEPPER_PXMCC;
2117 pxmc_axis_pt4mode(pxmc_state_t *mcs, int mode)
2119 static const typeof(*mcs->pxms_ptptr1) dummy0 = 0;
2122 if (mode == PXMC_AXIS_MODE_NOCHANGE)
2123 mode = pxmc_axis_rdmode(mcs);
2128 /* case PXMC_AXIS_MODE_STEPPER: */
2129 case PXMC_AXIS_MODE_STEPPER_PXMCC:
2130 case PXMC_AXIS_MODE_STEPPER_WITH_IRC:
2131 case PXMC_AXIS_MODE_STEPPER_WITH_IRC_PXMCC:
2132 res = pxmc_ptable_set_profile(mcs, &pxmc_ptprofile_sin, 0, 0);
2134 /*case PXMC_AXIS_MODE_STEPPER_WITH_PWM:*/
2135 case PXMC_AXIS_MODE_DC:
2136 /*profive some sane dummy values*/
2137 mcs->pxms_ptptr1 = (typeof(mcs->pxms_ptptr1))&dummy0;
2138 mcs->pxms_ptptr2 = (typeof(mcs->pxms_ptptr1))&dummy0;
2139 mcs->pxms_ptptr3 = (typeof(mcs->pxms_ptptr1))&dummy0;
2141 mcs->pxms_ptscale_mult=1;
2142 mcs->pxms_ptscale_shift=15;
2144 case PXMC_AXIS_MODE_BLDC:
2145 case PXMC_AXIS_MODE_BLDC_PXMCC:
2146 /* res = pxmc_init_ptable(mcs, PXMC_PTPROF_SIN3FUP); */
2147 #ifndef PXMC_WITH_PT_ZIC
2148 res = pxmc_ptable_set_profile(mcs, &pxmc_ptprofile_sin3phup, 0, 0);
2149 #else /*PXMC_WITH_PT_ZIC*/
2150 res = pxmc_ptable_set_profile(mcs, &pxmc_ptprofile_sin3phup_zic, 0, 0);
2151 #endif /*PXMC_WITH_PT_ZIC*/
2157 mcs->pxms_ptvang = pxmc_ptvang_deg2irc(mcs, 90);
2163 * pxmc_axis_mode - Sets axis mode.[extern API]
2164 * @mcs: Motion controller state information
2165 * @mode: 0 .. previous mode, 1 .. stepper motor mode,
2166 * 2 .. stepper motor with IRC feedback and PWM ,
2167 * 3 .. stepper motor with PWM control
2168 * 4 .. DC motor with IRC feedback and PWM
2172 pxmc_axis_mode(pxmc_state_t *mcs, int mode)
2177 pxmc_set_const_out(mcs, 0);
2178 pxmc_clear_flag(mcs, PXMS_ENI_b);
2179 pxmc_clear_flags(mcs,PXMS_ENO_m);
2180 /* Clear possible stall index flags from hardware */
2181 pxmc_inp_rocon_is_index_edge(mcs);
2182 pxmc_clear_flag(mcs, PXMS_PHA_b);
2183 pxmc_clear_flag(mcs, PXMS_PTI_b);
2186 prev_mode = pxmc_axis_rdmode(mcs);
2188 if (mode == PXMC_AXIS_MODE_NOCHANGE)
2193 mode = PXMC_AXIS_MODE_DC;
2195 if ((prev_mode == PXMC_AXIS_MODE_BLDC_PXMCC) ||
2196 (prev_mode == PXMCC_MODE_STEPPER_WITH_IRC))
2197 pxmcc_axis_setup(mcs, PXMCC_MODE_IDLE);
2199 res = pxmc_axis_pt4mode(mcs, mode);
2203 if (mcs->pxms_do_inp == pxmc_pxmcc_nofb_inp)
2204 mcs->pxms_do_inp = pxmc_inp_rocon_inp;
2205 if (mcs->pxms_do_con == pxmc_pxmcc_nofb_con)
2206 mcs->pxms_do_con = pxmc_pid_con;
2209 /*case PXMC_AXIS_MODE_STEPPER:*/
2210 case PXMC_AXIS_MODE_STEPPER_WITH_IRC:
2211 mcs->pxms_do_out = pxmc_rocon_pwm2ph_out;
2213 /*case PXMC_AXIS_MODE_STEPPER_WITH_PWM:*/
2214 case PXMC_AXIS_MODE_DC:
2215 mcs->pxms_do_out = pxmc_rocon_pwm_dc_out;
2217 case PXMC_AXIS_MODE_BLDC:
2218 mcs->pxms_do_out = pxmc_rocon_pwm3ph_out;
2220 case PXMC_AXIS_MODE_BLDC_PXMCC:
2221 if (pxmcc_axis_setup(mcs, PXMCC_MODE_BLDC) < 0)
2223 pxmcc_axis_enable(mcs, 1);
2224 mcs->pxms_do_out = pxmc_pxmcc_pwm3ph_out;
2226 case PXMC_AXIS_MODE_STEPPER_WITH_IRC_PXMCC:
2227 if (pxmcc_axis_setup(mcs, PXMCC_MODE_STEPPER_WITH_IRC) < 0)
2229 pxmcc_axis_enable(mcs, 1);
2230 mcs->pxms_do_out = pxmc_pxmcc_pwm2ph_out;
2232 case PXMC_AXIS_MODE_STEPPER_PXMCC:
2233 if (pxmcc_axis_setup(mcs, PXMCC_MODE_STEPPER) < 0)
2235 pxmcc_axis_enable(mcs, 1);
2236 mcs->pxms_do_inp = pxmc_pxmcc_nofb_inp;
2237 mcs->pxms_do_con = pxmc_pxmcc_nofb_con;
2238 mcs->pxms_do_out = pxmc_pxmcc_nofb2ph_out;
2244 /* Clear possible stall index flags from hardware */
2245 pxmc_inp_rocon_is_index_edge(mcs);
2246 /* Request new phases alignment for changed parameters */
2247 pxmc_clear_flag(mcs, PXMS_PHA_b);
2248 pxmc_clear_flag(mcs, PXMS_PTI_b);
2249 pxmc_set_flag(mcs, PXMS_ENI_b);
2253 void pxmc_sfi_isr(void)
2255 unsigned long spent = pxmc_fast_tick_time();
2258 pxmc_sfi_controller_and_output();
2259 pxmc_sfi_generator();
2261 /* Kick LX Master watchdog */
2262 if (pxmc_main_list.pxml_cnt != 0)
2263 *fpga_lx_master_transmitter_wdog = 1;
2265 spent = pxmc_fast_tick_time() - spent;
2267 if(spent > pxmc_sfi_spent_time_max)
2268 pxmc_sfi_spent_time_max = spent;
2272 int pxmc_clear_power_stop(void)
2277 int pxmc_process_state_check(unsigned long *pbusy_bits,
2278 unsigned long *perror_bits)
2281 unsigned short chan;
2282 unsigned long busy_bits = 0;
2283 unsigned long error_bits = 0;
2286 pxmc_for_each_mcs(chan, mcs) {
2288 flg |= mcs->pxms_flg;
2289 if (mcs->pxms_flg & PXMS_BSY_m)
2290 busy_bits |= 1 << chan;
2291 if (mcs->pxms_flg & PXMS_ERR_m)
2292 error_bits |= 1 << chan;
2295 if (appl_errstop_mode) {
2296 if((flg & PXMS_ENG_m) && (flg & PXMS_ERR_m)) {
2297 pxmc_for_each_mcs(chan, mcs) {
2298 if(mcs&&(mcs->pxms_flg & PXMS_ENG_m)) {
2305 if (pbusy_bits != NULL)
2306 *pbusy_bits = busy_bits;
2307 if (error_bits != NULL)
2308 *perror_bits = error_bits;
2318 if (!pxmc_main_list.pxml_cnt)
2321 pxmc_for_each_mcs(var, mcs)
2323 pxmc_set_const_out(mcs,0);
2326 pxmc_main_list.pxml_cnt = 0;
2332 int pxmc_initialize(void)
2337 pxmc_state_t *mcs = &mcs0.base;
2338 lpc_qei_state_t *qst = &lpc_qei_state;
2340 *fpga_irc_reset = 1;
2342 for (i = 0; i < 8; i++) {
2343 fpga_irc[i]->count = 0;
2344 fpga_irc[i]->count_index = 0;
2345 *fpga_irc_state[i] = FPGA_IRC_STATE_INDEX_EVENT_MASK;
2348 /* Initialize QEI module for IRC counting */
2349 pxmc_inp_lpc_qei_init(mcs->pxms_inp_info);
2351 /* Initialize QEI events processing */
2352 if (lpc_qei_setup_irq(qst) < 0)
2355 *fpga_irc_reset = 0;
2357 //res = pxmc_axis_pt4mode(mcs, PXMC_AXIS_MODE_BLDC);
2359 /*pxmc_ctm4pwm3f_wr(mcs, 0, 0, 0);*/
2360 //pxmc_rocon_pwm3ph_wr(mcs, 0, 0, 0);
2362 pxmc_rocon_pwm_master_init();
2363 #ifdef PXMC_ROCON_TIMED_BY_RX_DONE
2364 pxmc_rocon_rx_done_isr_setup(pxmc_rocon_rx_done_isr);
2365 #endif /*PXMC_ROCON_TIMED_BY_RX_DONE*/
2367 pxmc_main_list.pxml_cnt = 0;
2368 pxmc_dbg_hist = NULL;
2370 pxmc_main_list.pxml_cnt = PXML_MAIN_CNT;