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];
69 unsigned pxmc_rocon_lxpwr_chips = 0;
72 pxmc_rocon_state_t *pxmc_state2rocon_state(pxmc_state_t *mcs)
74 pxmc_rocon_state_t *mcsrc;
76 mcsrc = UL_CONTAINEROF(mcs, pxmc_rocon_state_t, base);
77 #else /*UL_CONTAINEROF*/
78 mcsrc = (pxmc_rocon_state_t*)((char*)mcs - __builtin_offsetof(pxmc_rocon_state_t, base));
79 #endif /*UL_CONTAINEROF*/
83 uint32_t pxmc_rocon_vin_adc_last;
84 int pxmc_rocon_vin_act;
85 int pxmc_rocon_vin_ofs = 20978;
86 int pxmc_rocon_vin_mul = 32905;
87 int pxmc_rocon_vin_shr = 14;
90 void pxmc_rocon_vin_compute(void)
92 volatile uint32_t *vin_adc_reg;
96 vin_adc_reg = fpga_lx_master_receiver_base;
97 vin_adc_reg += LX_MASTER_DATA_OFFS + 1 + 8 * 2;
99 vin_adc = *vin_adc_reg;
101 vin_act = (int16_t)(vin_adc - pxmc_rocon_vin_adc_last);
102 pxmc_rocon_vin_adc_last = vin_adc;
104 vin_act = (pxmc_rocon_vin_ofs - vin_act) * pxmc_rocon_vin_mul;
105 vin_act >>= pxmc_rocon_vin_shr;
107 pxmc_rocon_vin_act = vin_act;
110 unsigned int pxmc_rocon_rx_done_sqn;
111 unsigned int pxmc_rocon_rx_done_sqn_inc;
112 unsigned int pxmc_rocon_rx_done_sqn_misscnt;
113 unsigned int pxmc_rocon_rx_done_sqn_missoffs;
116 void pxmc_rocon_rx_done_sqn_compute(void)
120 unsigned int sqn_expect = pxmc_rocon_rx_done_sqn + pxmc_rocon_rx_done_sqn_inc;
122 sqn_act = *fpga_lx_master_receiver_done_div;
123 sqn_offs = (sqn_act - sqn_expect) & 0x1f;
125 if (pxmc_rocon_rx_done_sqn_missoffs != sqn_offs) {
126 pxmc_rocon_rx_done_sqn_misscnt = 1;
128 pxmc_rocon_rx_done_sqn_misscnt++;
129 if (pxmc_rocon_rx_done_sqn_misscnt >= 10)
130 sqn_expect += 1 - ((sqn_offs >> 3) & 2);
133 pxmc_rocon_rx_done_sqn_misscnt = 0;
135 pxmc_rocon_rx_done_sqn = sqn_expect;
136 pxmc_rocon_rx_done_sqn_missoffs = sqn_offs;
139 uint32_t pxmc_rocon_rx_err_cnt_last;
140 uint32_t pxmc_rocon_rx_err_level;
141 uint32_t pxmc_rocon_mcc_rx_done_sqn_last;
142 uint32_t pxmc_rocon_mcc_stuck;
145 void pxmc_rocon_rx_error_check(void)
149 pxmcc_data_t *mcc_data = pxmc_rocon_mcc_data();
151 cnt = mcc_data->common.rx_err_cnt;
152 pxmc_rocon_rx_err_level = cnt - pxmc_rocon_rx_err_cnt_last;
153 pxmc_rocon_rx_err_cnt_last = cnt;
155 mcc_sqn = mcc_data->common.rx_done_sqn;
156 pxmc_rocon_mcc_stuck = mcc_sqn == pxmc_rocon_mcc_rx_done_sqn_last? 1: 0;
157 pxmc_rocon_mcc_rx_done_sqn_last = mcc_sqn;
160 const uint8_t onesin10bits[1024]={
161 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,
162 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,
163 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,
164 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,
165 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,
166 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,
167 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,
168 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,
169 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,
170 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,
171 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,
172 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,
173 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,
174 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,
175 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,
176 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,
177 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,
178 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,
179 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,
180 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,
181 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,
182 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,
183 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,
184 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,
185 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,
186 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,
187 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,
188 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,
189 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,
190 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,
191 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,
192 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
196 pxmc_inp_rocon_inp(struct pxmc_state *mcs)
198 int chan=mcs->pxms_inp_info;
202 /* read position from hardware */
203 irc = fpga_irc[chan]->count;
204 irc += pxmc_rocon_irc_offset[chan];
205 pos = irc << PXMC_SUBDIV(mcs);
206 mcs->pxms_as = pos - mcs->pxms_ap;
209 /* Running of the motor commutator */
210 if (mcs->pxms_flg & PXMS_PTI_m)
211 pxmc_irc_16bit_commindx(mcs, irc);
217 pxmc_inp_rocon_is_mark(pxmc_state_t *mcs)
222 int chan=mcs->pxms_inp_info;
224 irc_state = *fpga_irc_state[chan];
226 mark = ((irc_state >> (ffs(FPGA_IRC_STATE_MARK_MASK) - 1)) ^
227 (mcs->pxms_cfg >> PXMS_CFG_HPS_b)) & 1;
229 filt = pxmc_rocon_mark_filt[chan];
230 filt = (filt << 1) | mark;
231 pxmc_rocon_mark_filt[chan] = filt;
233 return onesin10bits[filt & 0x03ff];
237 pxmc_inp_rocon_is_index_edge(pxmc_state_t *mcs)
241 int chan=mcs->pxms_inp_info;
243 irc_state = *fpga_irc_state[chan];
244 *fpga_irc_state[chan] = FPGA_IRC_STATE_INDEX_EVENT_MASK;
246 index = (irc_state >> (ffs(FPGA_IRC_STATE_INDEX_EVENT_MASK) - 1)) & 1;
252 pxmc_inp_rocon_adjust_to_irc_change(struct pxmc_state *mcs, long irc_diff)
254 long pos_diff = irc_diff << PXMC_SUBDIV(mcs);
256 mcs->pxms_ptofs += irc_diff;
258 mcs->pxms_ap += pos_diff;
259 mcs->pxms_rp += pos_diff;
264 pxmc_inp_rocon_irc_offset_from_index(struct pxmc_state *mcs)
266 int chan=mcs->pxms_inp_info;
270 irc_offset = -fpga_irc[chan]->count_index;
271 irc_diff = irc_offset - pxmc_rocon_irc_offset[chan];
272 pxmc_rocon_irc_offset[chan] = irc_offset;
273 return pxmc_inp_rocon_adjust_to_irc_change(mcs, irc_diff);
277 pxmc_inp_rocon_ap_zero(struct pxmc_state *mcs)
279 int chan=mcs->pxms_inp_info;
283 irc_offset = -fpga_irc[chan]->count;
284 irc_diff = irc_offset - pxmc_rocon_irc_offset[chan];
285 pxmc_rocon_irc_offset[chan] = irc_offset;
286 return pxmc_inp_rocon_adjust_to_irc_change(mcs, irc_diff);
290 pxmc_inp_rocon_ap2hw(struct pxmc_state *mcs)
292 int chan=mcs->pxms_inp_info;
296 irc = fpga_irc[chan]->count;
297 pos_diff = mcs->pxms_ap - (irc << PXMC_SUBDIV(mcs));
299 irc = pos_diff >> PXMC_SUBDIV(mcs);
301 /* Adjust phase table alignemt to modified IRC readout */
302 mcs->pxms_ptofs += irc - pxmc_rocon_irc_offset[chan];
304 pxmc_rocon_irc_offset[chan] = irc;
309 pxmc_inp_rocon_ptofs_from_index_poll(struct pxmc_state *mcs, int diff2err)
311 int chan=mcs->pxms_inp_info;
315 if (!(*fpga_irc_state[chan] & FPGA_IRC_STATE_INDEX_EVENT_MASK))
318 irc = fpga_irc[chan]->count + pxmc_rocon_irc_offset[chan];
319 index_irc = fpga_irc[chan]->count_index + pxmc_rocon_irc_offset[chan];
321 return pxmc_ptofs_from_index(mcs, irc, index_irc, diff2err);
324 uint32_t pxmc_rocon_receiver_dummy_reg;
326 static inline volatile uint32_t *
327 pxmc_rocon_receiver_chan2reg(unsigned chan)
329 volatile uint32_t *rec_reg;
332 return &pxmc_rocon_receiver_dummy_reg;
334 rec_reg = fpga_lx_master_receiver_base;
336 #ifdef LXPWR_WITH_SIROLADC
337 rec_reg += LX_MASTER_DATA_OFFS + 1 + (chan >> 3) * 3 + chan * 2;
338 #else /*LXPWR_WITH_SIROLADC*/
339 rec_reg += LX_MASTER_DATA_OFFS + chan;
340 #endif /*LXPWR_WITH_SIROLADC*/
346 pxmc_rocon_bldc_hal_rd(pxmc_state_t *mcs)
349 volatile uint32_t *rec_reg_a, *rec_reg_b, *rec_reg_c;
350 int chan = mcs->pxms_out_info;
353 #ifdef LXPWR_WITH_SIROLADC
355 #else /*LXPWR_WITH_SIROLADC*/
357 #endif /*LXPWR_WITH_SIROLADC*/
359 rec_reg_a = pxmc_rocon_receiver_chan2reg(chan + 0);
360 rec_reg_b = pxmc_rocon_receiver_chan2reg(chan + 1);
361 rec_reg_c = pxmc_rocon_receiver_chan2reg(chan + 2);
363 h = (rec_reg_a[hal_offs] >> 14) & 1;
364 h |= (rec_reg_b[hal_offs] >> 13) & 2;
365 h |= (rec_reg_c[hal_offs] >> 12) & 4;
367 /* return 3 bits corresponding to the HAL senzor input */
372 const unsigned char pxmc_lpc_bdc_hal_pos_table[8] =
384 const unsigned char pxmc_lpc_bdc_hal_pos_table[8] =
397 uint32_t pxmc_rocon_pwm_dummy_reg;
399 static inline volatile uint32_t *
400 pxmc_rocon_pwm_chan2reg(unsigned chan)
402 volatile uint32_t *pwm_reg;
405 return &pxmc_rocon_pwm_dummy_reg;
407 pwm_reg = fpga_lx_master_transmitter_base;
409 #ifdef LXPWR_WITH_SIROLADC
410 pwm_reg += LX_MASTER_DATA_OFFS + 1 + (chan >> 3) + chan;
411 #else /*LXPWR_WITH_SIROLADC*/
412 pwm_reg += LX_MASTER_DATA_OFFS + chan;
413 #endif /*LXPWR_WITH_SIROLADC*/
418 int pxmc_rocon_pwm_direct_wr(unsigned chan, unsigned pwm, int en)
420 volatile uint32_t *pwm_reg;
421 pwm_reg = pxmc_rocon_pwm_chan2reg(chan);
423 if (pwm_reg == &pxmc_rocon_pwm_dummy_reg)
426 *pwm_reg = pwm | (en? 0x4000: 0x8000);
432 * pxmc_rocon_pwm3ph_wr - Output of the 3-phase PWM to the hardware
433 * @mcs: Motion controller state information
435 /*static*/ inline void
436 pxmc_rocon_pwm3ph_wr(pxmc_state_t *mcs, short pwm1, short pwm2, short pwm3)
438 volatile uint32_t *pwm_reg_a, *pwm_reg_b, *pwm_reg_c;
439 int chan = mcs->pxms_out_info;
441 pwm_reg_c = pxmc_rocon_pwm_chan2reg(chan + 0);
442 pwm_reg_b = pxmc_rocon_pwm_chan2reg(chan + 1);
443 pwm_reg_a = pxmc_rocon_pwm_chan2reg(chan + 2);
451 pxmc_rocon_process_hal_error(struct pxmc_state *mcs)
453 if (mcs->pxms_halerc >= HAL_ERR_SENSITIVITY * HAL_ERR_MAX_COUNT)
455 pxmc_set_errno(mcs, PXMS_E_HAL);
460 mcs->pxms_halerc += HAL_ERR_SENSITIVITY;
464 * pxmc_rocon_pwm3ph_out - Phase output for brush-less 3-phase motor
465 * @mcs: Motion controller state information
468 pxmc_rocon_pwm3ph_out(pxmc_state_t *mcs)
470 typeof(mcs->pxms_ptvang) ptvang;
472 unsigned char hal_pos;
480 if (!(mcs->pxms_flg & PXMS_PTI_m) || !(mcs->pxms_flg & PXMS_PHA_m) ||
481 (mcs->pxms_flg & PXMS_PRA_m))
484 short ptirc = mcs->pxms_ptirc;
485 short divisor = mcs->pxms_ptper * 6;
488 pxmc_irc_16bit_commindx(mcs, mcs->pxms_rp >> PXMC_SUBDIV(mcs));
493 res = pxmc_inp_rocon_ptofs_from_index_poll(mcs, 0);
495 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
497 pxmc_set_flag(mcs, PXMS_PTI_b);
498 pxmc_set_flag(mcs, PXMS_PHA_b);
503 hal_pos = pxmc_lpc_bdc_hal_pos_table[pxmc_rocon_bldc_hal_rd(mcs)];
508 pxmc_rocon_process_hal_error(mcs);
512 if (mcs->pxms_halerc)
515 ptindx = (hal_pos * ptirc + divisor / 2) / divisor;
517 if (!(mcs->pxms_flg & PXMS_PTI_m) || (mcs->pxms_flg & PXMS_PRA_m))
519 if (((hal_pos != mcs->pxms_hal) && (mcs->pxms_hal != 0x40)) && 1)
521 short ptindx_prev = (mcs->pxms_hal * ptirc + divisor / 2) / divisor;;
523 if ((ptindx > ptindx_prev + ptirc / 2) ||
524 (ptindx_prev > ptindx + ptirc / 2))
526 ptindx = (ptindx_prev + ptindx - ptirc) / 2;
533 ptindx = (ptindx_prev + ptindx) / 2;
536 mcs->pxms_ptindx = ptindx;
538 mcs->pxms_ptofs = (mcs->pxms_ap >> PXMC_SUBDIV(mcs)) + mcs->pxms_ptshift - ptindx;
540 pxmc_set_flag(mcs, PXMS_PTI_b);
541 pxmc_clear_flag(mcs, PXMS_PRA_b);
545 if (!(mcs->pxms_flg & PXMS_PTI_m))
546 mcs->pxms_ptindx = ptindx;
549 /* if phase table position to mask is know do fine phase table alignment */
550 if (mcs->pxms_cfg & PXMS_CFG_I2PT_m) {
552 res = pxmc_inp_rocon_ptofs_from_index_poll(mcs, 0);
554 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
556 pxmc_set_flag(mcs, PXMS_PTI_b);
557 pxmc_set_flag(mcs, PXMS_PHA_b);
561 mcs->pxms_hal = hal_pos;
567 /*wind_current[0]=(ADC->ADDR0 & 0xFFF0)>>4;*/
568 /* FIXME - check winding current against limit */
569 /* pxmc_set_errno(mcs, PXMS_E_WINDCURRENT); */
573 ptvang = mcs->pxms_ptvang;
577 ene = mcs->pxms_flg & PXMS_BSY_m? mcs->pxms_me: 0;
581 indx = mcs->pxms_ptindx;
583 /* tuning of magnetic field/voltage advance angle */
584 indx += (mcs->pxms_s1 * mcs->pxms_as) >> (PXMC_SUBDIV(mcs) + 8);
589 /* Generating direction of stator mag. field for backward torque */
592 if ((indx -= ptvang) < 0)
593 indx += mcs->pxms_ptirc;
597 /* Generating direction of stator mag. field for forward torque */
598 if ((indx += ptvang) >= mcs->pxms_ptirc)
599 indx -= mcs->pxms_ptirc;
602 if (mcs->pxms_ptscale_mult)
603 indx = ((unsigned long)indx * mcs->pxms_ptscale_mult) >> mcs->pxms_ptscale_shift;
605 pwm1 = mcs->pxms_ptptr1[indx];
606 pwm2 = mcs->pxms_ptptr2[indx];
607 pwm3 = mcs->pxms_ptptr3[indx];
609 #ifdef PXMC_WITH_PT_ZIC
610 if (labs(mcs->pxms_as) < (10 << PXMC_SUBDIV(mcs)))
612 pwm1 &= ~PXMC_PT_ZIC_MASK;
613 pwm2 &= ~PXMC_PT_ZIC_MASK;
614 pwm3 &= ~PXMC_PT_ZIC_MASK;
616 #endif /*PXMC_WITH_PT_ZIC*/
618 /* Default phase-table amplitude is 0x7fff, ene max is 0x7fff */
619 /* Initialized CTM4 PWM period is 0x200 => divide by value about 2097024 */
621 unsigned long pwm_dc = pxmc_rocon_pwm_magnitude * (unsigned long)ene;
622 if (pwm1 & PXMC_PT_ZIC_MASK)
625 pwm1 = (((unsigned long long)pwm1 * pwm_dc) >> (15 + 15)) | 0x4000;
626 if (pwm2 & PXMC_PT_ZIC_MASK)
629 pwm2 = (((unsigned long long)pwm2 * pwm_dc) >> (15 + 15)) | 0x4000;
630 if (pwm3 & PXMC_PT_ZIC_MASK)
633 pwm3 = (((unsigned long long)pwm3 * pwm_dc) >> (15 + 15)) | 0x4000;
635 pxmc_rocon_pwm3ph_wr(mcs, pwm1, pwm2, pwm3);
639 pxmc_rocon_pwm3ph_wr(mcs, 0, 0, 0);
646 * pxmc_rocon_pwm2ph_wr - Output of the 2-phase stepper motor PWM to the hardware
647 * @mcs: Motion controller state information
649 /*static*/ inline void
650 pxmc_rocon_pwm2ph_wr(pxmc_state_t *mcs, short pwm1, short pwm2)
652 volatile uint32_t *pwm_reg_ap, *pwm_reg_an, *pwm_reg_bp, *pwm_reg_bn;
653 int chan = mcs->pxms_out_info;
655 pwm_reg_bn = pxmc_rocon_pwm_chan2reg(chan + 0);
656 pwm_reg_bp = pxmc_rocon_pwm_chan2reg(chan + 1);
657 pwm_reg_an = pxmc_rocon_pwm_chan2reg(chan + 2);
658 pwm_reg_ap = pxmc_rocon_pwm_chan2reg(chan + 3);
661 *pwm_reg_bp = pwm2 | 0x4000;
665 *pwm_reg_bn = -pwm2 | 0x4000;
669 *pwm_reg_ap = pwm1 | 0x4000;
673 *pwm_reg_an = -pwm1 | 0x4000;
678 * pxmc_rocon_pwm2ph_out - Phase output of the 2-phase stepper motor PWM
679 * @mcs: Motion controller state information
682 pxmc_rocon_pwm2ph_out(pxmc_state_t *mcs)
684 typeof(mcs->pxms_ptvang) ptvang;
692 if(!(mcs->pxms_flg&PXMS_PTI_m) || !(mcs->pxms_flg&PXMS_PHA_m) ||
693 (mcs->pxms_flg&PXMS_PRA_m)){
695 short ptirc=mcs->pxms_ptirc;
698 pxmc_irc_16bit_commindx(mcs, mcs->pxms_rp >> PXMC_SUBDIV(mcs));
703 res = pxmc_inp_rocon_ptofs_from_index_poll(mcs, 0);
705 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
707 pxmc_set_flag(mcs, PXMS_PTI_b);
708 pxmc_set_flag(mcs, PXMS_PHA_b);
713 ptindx = mcs->pxms_ptindx;
715 if(0 && (!(mcs->pxms_flg&PXMS_PTI_m) || (mcs->pxms_flg&PXMS_PRA_m))) {
717 mcs->pxms_ptindx = ptindx;
719 mcs->pxms_ptofs = (mcs->pxms_ap >> PXMC_SUBDIV(mcs)) + mcs->pxms_ptshift - ptindx;
721 pxmc_set_flag(mcs, PXMS_PTI_b);
722 pxmc_clear_flag(mcs, PXMS_PRA_b);
724 /* if phase table position to mask is know do fine phase table alignment */
725 //if(mcs->pxms_cfg & PXMS_CFG_I2PT_m)
726 // lpc_qei_setup_index_catch(&lpc_qei_state);
729 if(!(mcs->pxms_flg&PXMS_PTI_m))
730 mcs->pxms_ptindx = ptindx;
736 /*wind_current[0]=(ADC->ADDR0 & 0xFFF0)>>4;*/
737 /* FIXME - check winding current against limit */
738 /* pxmc_set_errno(mcs, PXMS_E_WINDCURRENT); */
742 ptvang = mcs->pxms_ptvang;
746 ene = mcs->pxms_flg & PXMS_BSY_m? mcs->pxms_me: 0;
750 indx = mcs->pxms_ptindx;
752 /* tuning of magnetic field/voltage advance angle */
753 indx += (mcs->pxms_s1 * mcs->pxms_as) >> (PXMC_SUBDIV(mcs) + 8);
756 /* Generating direction of stator mag. field for backward torque */
758 if ((indx -= ptvang)<0)
759 indx += mcs->pxms_ptirc;
761 /* Generating direction of stator mag. field for forward torque */
762 if ((indx += ptvang) >= mcs->pxms_ptirc)
763 indx -= mcs->pxms_ptirc;
766 if (mcs->pxms_ptscale_mult)
767 indx = ((unsigned long)indx * mcs->pxms_ptscale_mult) >> mcs->pxms_ptscale_shift;
769 pwm1 = mcs->pxms_ptptr1[indx];
770 pwm2 = mcs->pxms_ptptr2[indx];
772 /* Default phase-table amplitude is 0x7fff, ene max is 0x7fff */
773 /* Initialized PWM period is 0x200 => divide by value about 2097024 */
775 unsigned long pwm_dc = pxmc_rocon_pwm_magnitude * (unsigned long)ene;
776 pwm1 = ((unsigned long long)pwm1 * pwm_dc) >> (15+15);
777 pwm2 = ((unsigned long long)pwm2 * pwm_dc) >> (15+15);
779 pxmc_rocon_pwm2ph_wr(mcs, pwm1, pwm2);
781 /*pxmc_lpc_wind_current_over_cnt = 0;*/
782 pxmc_rocon_pwm2ph_wr(mcs, 0, 0);
789 * pxmc_rocon_pwm_dc_out - DC motor CW and CCW PWM output
790 * @mcs: Motion controller state information
793 pxmc_rocon_pwm_dc_out(pxmc_state_t *mcs)
795 volatile uint32_t *pwm_reg_a, *pwm_reg_b;
796 int chan = mcs->pxms_out_info;
797 int ene = mcs->pxms_ene;
799 pwm_reg_a = pxmc_rocon_pwm_chan2reg(chan + 0);
800 pwm_reg_b = pxmc_rocon_pwm_chan2reg(chan + 1);
806 ene = (ene * (pxmc_rocon_pwm_magnitude + 5)) >> 15;
808 *pwm_reg_b = ene | 0x4000;
812 ene = (ene * (pxmc_rocon_pwm_magnitude + 5)) >> 15;
814 *pwm_reg_a = ene | 0x4000;
820 /*******************************************************************/
821 /* PXMCC - PXMC coprocessor support and communication */
823 void pxmcc_pxmc_ptofs2mcc(pxmc_state_t *mcs, int enable_update)
825 volatile pxmcc_axis_data_t *mcc_axis = pxmc_rocon_mcs2pxmcc(mcs);
826 int inp_chan=mcs->pxms_inp_info;
830 if (mcc_axis != NULL) {
831 if (enable_update >= 0)
832 mcc_axis->ptirc = 0xffffffff;
833 ptofs = mcs->pxms_ptofs - pxmc_rocon_irc_offset[inp_chan];
834 irc = fpga_irc[inp_chan]->count;
835 ptofs = (int16_t)(ptofs - irc) + irc;
836 mcc_axis->ptofs = ptofs;
837 if (enable_update > 0) {
838 mcc_axis->ptirc = mcs->pxms_ptirc;
844 void pxmcc_axis_get_cur_dq_filt_raw(pxmc_state_t *mcs,
845 int32_t *p_cur_d_raw, int32_t *p_cur_q_raw)
847 volatile pxmcc_axis_data_t *mcc_axis = pxmc_rocon_mcs2pxmcc(mcs);
848 pxmc_rocon_state_t *mcsrc = pxmc_state2rocon_state(mcs);
849 uint32_t cur_d_cum = mcc_axis->cur_d_cum;
850 uint32_t cur_q_cum = mcc_axis->cur_q_cum;
854 cur_d = cur_d_cum - mcsrc->cur_d_cum_prev;
855 mcsrc->cur_d_cum_prev = cur_d_cum;
856 cur_q = cur_q_cum - mcsrc->cur_q_cum_prev;
857 mcsrc->cur_q_cum_prev = cur_q_cum;
859 *p_cur_d_raw = cur_d;
860 *p_cur_q_raw = cur_q;
864 void pxmcc_axis_cur_dq_raw2filt(int *p_cur, int32_t cur_raw)
868 cur_div = cur_raw & 0x1f;
869 cur = cur_raw / cur_div;
870 cur += (1 << 11) | 0x20;
875 void pxmcc_axis_get_cur_dq_filt(pxmc_state_t *mcs, int *p_cur_d, int *p_cur_q)
880 pxmcc_axis_get_cur_dq_filt_raw(mcs, &cur_d_raw, &cur_q_raw);
882 pxmcc_axis_cur_dq_raw2filt(p_cur_d, cur_d_raw);
883 pxmcc_axis_cur_dq_raw2filt(p_cur_q, cur_q_raw);
887 void pxmcc_cur_ctrl_pi(int *p_pwm, int32_t *p_cur_err_sum,
888 int cur_err, short cur_ctrl_p, short cur_ctrl_i, int max_pwm)
891 int32_t cur_err_sum = *p_cur_err_sum;
893 pwm = (cur_err * cur_ctrl_p) >> 8;
896 cur_err_sum += cur_err * cur_ctrl_i;
900 pwm += cur_err_sum >> 16;
903 cur_err_sum -= (pwm - max_pwm) << 16;
905 } else if (-pwm > max_pwm) {
906 cur_err_sum -= (pwm + max_pwm) << 16;
909 *p_cur_err_sum = cur_err_sum;
914 pxmc_pxmcc_pwm3ph_out(pxmc_state_t *mcs)
918 pxmc_rocon_state_t *mcsrc = pxmc_state2rocon_state(mcs);
920 if (!(mcs->pxms_flg & PXMS_PTI_m) || !(mcs->pxms_flg & PXMS_PHA_m) ||
921 (mcs->pxms_flg & PXMS_PRA_m)) {
923 short ptirc = mcs->pxms_ptirc;
924 short divisor = mcs->pxms_ptper * 6;
925 unsigned char hal_pos;
927 hal_pos = pxmc_lpc_bdc_hal_pos_table[pxmc_rocon_bldc_hal_rd(mcs)];
929 if (hal_pos == 0xff) {
931 pxmc_rocon_process_hal_error(mcs);
933 if (mcs->pxms_halerc)
936 ptindx = (hal_pos * ptirc + divisor / 2) / divisor;
938 if (!(mcs->pxms_flg & PXMS_PTI_m) || (mcs->pxms_flg & PXMS_PRA_m)) {
939 int set_ptofs_fl = 0;
940 int ptofs_enable_update = 0;
942 if (((hal_pos != mcs->pxms_hal) && (mcs->pxms_hal != 0x40)) && 1) {
943 short ptindx_prev = (mcs->pxms_hal * ptirc + divisor / 2) / divisor;;
945 if ((ptindx > ptindx_prev + ptirc / 2) ||
946 (ptindx_prev > ptindx + ptirc / 2)) {
947 ptindx = (ptindx_prev + ptindx - ptirc) / 2;
952 ptindx = (ptindx_prev + ptindx) / 2;
956 ptofs_enable_update = 1;
958 pxmc_set_flag(mcs, PXMS_PTI_b);
959 pxmc_clear_flag(mcs, PXMS_PRA_b);
961 if (!(mcs->pxms_flg & PXMS_PTI_m))
965 mcs->pxms_ptindx = ptindx;
966 mcs->pxms_ptofs = (mcs->pxms_ap >> PXMC_SUBDIV(mcs)) + mcs->pxms_ptshift - ptindx;
968 pxmcc_pxmc_ptofs2mcc(mcs, ptofs_enable_update);
971 /* if phase table position to mask is know do fine phase table alignment */
972 if (mcs->pxms_cfg & PXMS_CFG_I2PT_m) {
975 res = pxmc_inp_rocon_ptofs_from_index_poll(mcs, 0);
977 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
979 pxmcc_pxmc_ptofs2mcc(mcs, 1);
980 pxmc_set_flag(mcs, PXMS_PTI_b);
981 pxmc_set_flag(mcs, PXMS_PHA_b);
985 mcs->pxms_hal = hal_pos;
989 pxmcc_axis_get_cur_dq_filt_raw(mcs, &cur_d_raw, &cur_q_raw);
992 /*wind_current[0]=(ADC->ADDR0 & 0xFFF0)>>4;*/
993 /* FIXME - check winding current against limit */
994 /* pxmc_set_errno(mcs, PXMS_E_WINDCURRENT); */
998 int ene, pwm_d, pwm_q;
1000 ene = mcs->pxms_ene;
1002 pwm_q = (pxmc_rocon_pwm_magnitude * ene) >> 15;
1004 if (mcs->pxms_flg & (PXMS_ENR_m | PXMS_ENO_m)) {
1006 int cur_d_req, cur_d_err;
1007 int max_pwm = (pxmc_rocon_pwm_magnitude * mcs->pxms_me) >> 15;
1011 pxmcc_axis_cur_dq_raw2filt(&cur_d, cur_d_raw);
1013 cur_d_err = cur_d_req - cur_d;
1015 pxmcc_cur_ctrl_pi(&pwm_d, &mcsrc->cur_d_err_sum, cur_d_err,
1016 mcsrc->cur_d_p, mcsrc->cur_d_i, max_pwm);
1018 if (pxmc_rocon_rx_err_level >= 2)
1019 pxmc_set_errno(mcs, PXMS_E_WINDCURADC);
1020 else if (pxmc_rocon_mcc_stuck)
1021 pxmc_set_errno(mcs, PXMS_E_MCC_FAULT);
1024 pxmcc_axis_pwm_dq_out(mcs, pwm_d, pwm_q);
1026 if (mcs->pxms_flg & PXMS_ERR_m)
1027 pxmc_rocon_pwm3ph_wr(mcs, 0, 0, 0);
1034 pxmc_pxmcc_pwm2ph_out(pxmc_state_t *mcs)
1036 pxmc_rocon_state_t *mcsrc = pxmc_state2rocon_state(mcs);
1040 pxmcc_axis_get_cur_dq_filt_raw(mcs, &cur_d_raw, &cur_q_raw);
1042 if(!(mcs->pxms_flg&PXMS_PTI_m) || !(mcs->pxms_flg&PXMS_PHA_m) ||
1043 (mcs->pxms_flg&PXMS_PRA_m)) {
1046 /* Wait for index mark to align phases */
1048 res = pxmc_inp_rocon_ptofs_from_index_poll(mcs, 0);
1050 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
1052 pxmcc_pxmc_ptofs2mcc(mcs, 1);
1053 pxmc_set_flag(mcs, PXMS_PTI_b);
1054 pxmc_set_flag(mcs, PXMS_PHA_b);
1056 pxmcc_pxmc_ptofs2mcc(mcs, 0);
1062 int ene, pwm_d, pwm_q;
1064 ene = mcs->pxms_ene;
1067 if (mcs->pxms_flg & PXMS_PHA_m &&
1068 (mcs->pxms_flg & (PXMS_ENR_m | PXMS_ENO_m))) {
1070 int cur_d_req, cur_d_err;
1071 int max_pwm = (pxmc_rocon_pwm_magnitude * mcs->pxms_me) >> 15;
1075 pxmcc_axis_cur_dq_raw2filt(&cur_d, cur_d_raw);
1077 cur_d_err = cur_d_req - cur_d;
1079 pxmcc_cur_ctrl_pi(&pwm_d, &mcsrc->cur_d_err_sum, cur_d_err,
1080 mcsrc->cur_d_p, mcsrc->cur_d_i, max_pwm);
1082 if (pxmc_rocon_rx_err_level >= 2)
1083 pxmc_set_errno(mcs, PXMS_E_WINDCURADC);
1084 else if (pxmc_rocon_mcc_stuck)
1085 pxmc_set_errno(mcs, PXMS_E_MCC_FAULT);
1088 pwm_q = (pxmc_rocon_pwm_magnitude * ene) >> 15;
1090 pxmcc_axis_pwm_dq_out(mcs, pwm_d, pwm_q);
1092 if (mcs->pxms_flg & PXMS_ERR_m)
1093 pxmc_rocon_pwm2ph_wr(mcs, 0, 0);
1100 * pxmc_pxmcc_nofb2ph_inp - Dummy input for direct stepper motor control
1101 * @mcs: Motion controller state information
1104 pxmc_pxmcc_nofb2ph_inp(pxmc_state_t *mcs)
1106 volatile pxmcc_axis_data_t *mcc_axis = pxmc_rocon_mcs2pxmcc(mcs);
1107 uint32_t steps_pos_act = mcc_axis->steps_pos;
1108 mcs->pxms_as = (int32_t)(steps_pos_act - mcs->pxms_ap);
1109 mcs->pxms_ap += mcs->pxms_as;
1114 * pxmc_pxmcc_nofb_con - Empty controller for direct stepper motor control
1115 * @mcs: Motion controller state information
1118 pxmc_pxmcc_nofb_con(pxmc_state_t *mcs)
1120 mcs->pxms_ene=mcs->pxms_me;
1125 pxmc_pxmcc_nofb2ph_out(pxmc_state_t *mcs)
1127 pxmc_rocon_state_t *mcsrc = pxmc_state2rocon_state(mcs);
1128 volatile pxmcc_axis_data_t *mcc_axis = pxmc_rocon_mcs2pxmcc(mcs);
1132 pxmcc_axis_get_cur_dq_filt_raw(mcs, &cur_d_raw, &cur_q_raw);
1134 if ((mcs->pxms_flg & PXMS_ERR_m) ||
1135 !(mcs->pxms_flg & (PXMS_ENO_m | PXMS_ENR_m))) {
1136 pxmc_rocon_pwm2ph_wr(mcs, 0, 0);
1137 pxmcc_axis_pwm_dq_out(mcs, 0, 0);
1138 mcc_axis->steps_inc = 0;
1139 mcc_axis->steps_inc_next = 0;
1140 mcsrc->cur_d_err_sum = 0;
1141 mcsrc->cur_q_err_sum = 0;
1145 int cur_d_req, cur_d_err;
1146 int cur_q_req, cur_q_err;
1147 int max_pwm = mcs->pxms_me;
1151 pxmcc_axis_cur_dq_raw2filt(&cur_d, cur_d_raw);
1152 pxmcc_axis_cur_dq_raw2filt(&cur_q, cur_q_raw);
1157 cur_d_req = mcsrc->cur_hold;
1159 cur_d_err = cur_d_req - cur_d;
1161 pxmcc_cur_ctrl_pi(&pwm_d, &mcsrc->cur_d_err_sum, cur_d_err,
1162 mcsrc->cur_d_p, mcsrc->cur_d_i, max_pwm);
1164 /* pwm_d = (pxmc_rocon_pwm_magnitude * ene) >> 15; */
1168 cur_q_err = cur_q_req - cur_q;
1170 pxmcc_cur_ctrl_pi(&pwm_q, &mcsrc->cur_q_err_sum, cur_q_err,
1171 mcsrc->cur_q_p, mcsrc->cur_q_i, max_pwm);
1173 pxmcc_axis_pwm_dq_out(mcs, pwm_d, pwm_q);
1175 stpinc = mcs->pxms_rp - mcsrc->steps_pos_prev;
1177 stpdiv = pxmc_rocon_rx_done_sqn_inc;
1178 mcc_axis->steps_inc_next = (stpinc + stpdiv / 2) / stpdiv;
1179 mcc_axis->steps_pos_next = mcsrc->steps_pos_prev;
1181 mcsrc->steps_pos_prev = mcs->pxms_rp;
1183 mcc_axis->steps_sqn_next = pxmc_rocon_rx_done_sqn +
1184 pxmc_rocon_rx_done_sqn_inc - 1;
1186 if (pxmc_rocon_rx_err_level >= 2)
1187 pxmc_set_errno(mcs, PXMS_E_WINDCURADC);
1188 else if (pxmc_rocon_mcc_stuck)
1189 pxmc_set_errno(mcs, PXMS_E_MCC_FAULT);
1195 int pxmcc_axis_setup(pxmc_state_t *mcs, int mode)
1197 volatile pxmcc_data_t *mcc_data = pxmc_rocon_mcc_data();
1198 volatile pxmcc_axis_data_t *mcc_axis = pxmc_rocon_mcs2pxmcc(mcs);
1199 pxmc_rocon_state_t *mcsrc = pxmc_state2rocon_state(mcs);
1203 uint32_t pwmtx_info;
1204 uint32_t pwmtx_info_dummy = 27;
1210 if (mcc_axis == NULL)
1213 if (mcc_data->common.fwversion != PXMCC_FWVERSION)
1216 mcc_axis->ccflg = 0;
1217 mcc_axis->mode = PXMCC_MODE_IDLE;
1219 mcc_data->common.pwm_cycle = PXMC_LXPWR_PWM_CYCLE;
1221 ptirc = mcs->pxms_ptirc;
1222 if (mode == PXMCC_MODE_STEPPER)
1223 ptirc <<= PXMC_SUBDIV(mcs);
1225 ull = (1ULL << 32) * mcs->pxms_ptper;
1226 ptreci = (ull + ptirc / 2) / ptirc;
1228 mcc_axis->ptreci = ptreci;
1230 pxmcc_pxmc_ptofs2mcc(mcs, 0);
1232 inp_info = (char*)&fpga_irc[mcs->pxms_inp_info]->count - (char*)fpga_irc[0];
1233 inp_info += mcc_data->common.irc_base;
1236 case PXMCC_MODE_IDLE:
1239 case PXMCC_MODE_BLDC:
1242 case PXMCC_MODE_STEPPER_WITH_IRC:
1245 case PXMCC_MODE_STEPPER:
1247 inp_info = (char*)&mcc_axis->steps_pos - (char*)mcc_data;
1251 mcc_axis->inp_info = inp_info;
1252 mcc_axis->out_info = mcs->pxms_out_info;
1254 pwm_chan = mcs->pxms_out_info;
1256 pwmtx_info = (pwmtx_info_dummy << 0) | (pwmtx_info_dummy << 8) |
1257 (pwmtx_info_dummy << 16) | (pwmtx_info_dummy << 24);
1259 for (i = phcnt; --i >= 0; ) {
1260 volatile uint32_t *pwm_reg;
1261 volatile uint32_t *pwm_reg_base = fpga_lx_master_transmitter_base;
1265 pwm_reg = pxmc_rocon_pwm_chan2reg(pwm_chan + i);
1266 if (pwm_reg == &pxmc_rocon_pwm_dummy_reg) {
1267 pwmtx_info |= pwmtx_info_dummy;
1269 pwmtx_info |= pwm_reg - pwm_reg_base;
1273 mcc_axis->pwmtx_info = pwmtx_info;
1275 mcc_axis->mode = mode;
1277 mcc_axis->ccflg = 0;
1278 mcc_axis->pwm_dq = 0;
1280 if (mode == PXMCC_MODE_STEPPER) {
1281 mcsrc->steps_pos_prev = mcs->pxms_rp = mcs->pxms_ap;
1282 mcs->pxms_rs = mcs->pxms_as = 0;
1283 mcc_axis->steps_inc_next = 0;
1284 mcc_axis->steps_pos_next = mcsrc->steps_pos_prev;
1285 mcc_axis->steps_inc = 0;
1286 mcc_axis->steps_pos = mcsrc->steps_pos_prev;
1287 mcc_axis->ptirc = mcs->pxms_ptirc << PXMC_SUBDIV(mcs);
1289 pxmcc_pxmc_ptofs2mcc(mcs, 1);
1294 int pxmcc_curadc_zero(int wait)
1297 unsigned try = wait? 200: 0;
1298 volatile pxmcc_data_t *mcc_data = pxmc_rocon_mcc_data();
1299 volatile pxmcc_curadc_data_t *curadc;
1301 for (chan = 0; chan < PXMCC_CURADC_CHANNELS; chan++)
1302 pxmc_rocon_pwm_direct_wr(chan, 0, 0);
1305 if (mcc_data->common.fwversion == PXMCC_FWVERSION)
1312 if (pxmc_rocon_wait_rx_done() < 0)
1315 if (pxmc_rocon_wait_rx_done() < 0)
1319 for (chan = 0; chan < PXMCC_CURADC_CHANNELS; chan++) {
1320 curadc = mcc_data->curadc + chan;
1321 curadc->siroladc_offs += curadc->cur_val;
1327 /*******************************************************************/
1329 volatile void *pxmc_rocon_rx_data_hist_buff;
1330 volatile void *pxmc_rocon_rx_data_hist_buff_end;
1331 int pxmc_rocon_rx_data_hist_mode;
1333 uint32_t pxmc_rocon_rx_last_irq;
1334 uint32_t pxmc_rocon_rx_cycle_time;
1335 uint32_t pxmc_rocon_rx_irq_latency;
1336 uint32_t pxmc_rocon_rx_irq_latency_max;
1338 IRQ_HANDLER_FNC(pxmc_rocon_rx_done_isr)
1342 ir = ROCON_RX_TIM->IR & LPC_TIM_IR_ALL_m;
1343 ROCON_RX_TIM->IR = ir;
1344 if (ir & LPC_TIM_IR_CR1INT_m) {
1346 cr0 = ROCON_RX_TIM->CR0;
1347 cr1 = ROCON_RX_TIM->CR1;
1349 pxmc_rocon_rx_cycle_time = cr1 - pxmc_rocon_rx_last_irq;
1350 pxmc_rocon_rx_last_irq = cr1;
1352 hal_gpio_set_value(T2MAT0_PIN, 1);
1353 hal_gpio_set_value(T2MAT1_PIN, 0);
1354 hal_gpio_set_value(T2MAT0_PIN, 0);
1356 pxmc_rocon_rx_done_sqn_compute();
1357 pxmc_rocon_vin_compute();
1358 pxmc_rocon_rx_error_check();
1360 if (pxmc_rocon_rx_data_hist_buff >= pxmc_rocon_rx_data_hist_buff_end)
1361 pxmc_rocon_rx_data_hist_buff = NULL;
1363 if (pxmc_rocon_rx_data_hist_buff != NULL) {
1364 if (pxmc_rocon_rx_data_hist_mode == 0) {
1366 volatile uint32_t *pwm_reg = fpga_lx_master_transmitter_base + 8;
1367 volatile uint32_t *rec_reg = fpga_lx_master_receiver_base + 8;
1368 uint16_t *pbuf = (uint16_t *)pxmc_rocon_rx_data_hist_buff;
1369 for (i = 0; i < 8; i++) {
1370 *(pbuf++) = *(rec_reg++);
1372 for (i = 0; i < 8; i++) {
1373 *(pbuf++) = *(pwm_reg++);
1375 pxmc_rocon_rx_data_hist_buff = pbuf;
1376 } else if (pxmc_rocon_rx_data_hist_mode == 1) {
1378 uint32_t *pbuf = (uint32_t *)pxmc_rocon_rx_data_hist_buff;
1379 pxmcc_data_t *mcc_data = pxmc_rocon_mcc_data();
1380 pxmcc_axis_data_t *mcc_axis = mcc_data->axis + 0;
1381 uint32_t *ptumbl = (uint32_t *)mcc_axis;
1383 for (i = 0; i < 16; i++)
1384 *(pbuf++) = *(ptumbl++);
1386 pxmc_rocon_rx_data_hist_buff = pbuf;
1390 pxmc_rocon_rx_irq_latency = ROCON_RX_TIM->TC - cr1;
1391 if (pxmc_rocon_rx_irq_latency > pxmc_rocon_rx_irq_latency_max)
1392 pxmc_rocon_rx_irq_latency_max = pxmc_rocon_rx_irq_latency;
1394 #ifdef PXMC_ROCON_TIMED_BY_RX_DONE
1397 #endif /*PXMC_ROCON_TIMED_BY_RX_DONE*/
1404 pxmc_rocon_rx_done_isr_setup(irq_handler_t rx_done_isr_handler)
1407 disable_irq(ROCON_RX_IRQn);
1409 hal_pin_conf_set(T2MAT0_PIN, PORT_CONF_GPIO_OUT_LO);
1410 hal_pin_conf_set(T2MAT1_PIN, PORT_CONF_GPIO_OUT_LO);
1411 hal_pin_conf(T2CAP0_PIN);
1412 hal_pin_conf(T2CAP1_PIN);
1414 hal_gpio_direction_output(T2MAT0_PIN, 1);
1415 hal_gpio_direction_output(T2MAT1_PIN, 0);
1416 hal_gpio_set_value(T2MAT0_PIN, 0);
1418 /* Enable CLKOUT pin function, source CCLK, divide by 1 */
1419 LPC_SC->CLKOUTCFG = 0x0100;
1421 request_irq(ROCON_RX_IRQn, rx_done_isr_handler, 0, NULL,NULL);
1423 ROCON_RX_TIM->TCR = 0;
1424 ROCON_RX_TIM->CTCR = 0;
1425 ROCON_RX_TIM->PR = 0; /* Divide by 1 */
1427 ROCON_RX_TIM->CCR = LPC_TIM_CCR_CAP0RE_m | LPC_TIM_CCR_CAP1FE_m |
1428 LPC_TIM_CCR_CAP1I_m;
1430 ROCON_RX_TIM->EMR = __val2mfld(LPC_TIM_EMR_EMC0_m, LPC_TIM_EMR_NOP) |
1431 __val2mfld(LPC_TIM_EMR_EMC1_m, LPC_TIM_EMR_NOP);
1433 ROCON_RX_TIM->MCR = 0; /* No IRQ on MRx */
1434 ROCON_RX_TIM->TCR = LPC_TIM_TCR_CEN_m; /* Enable timer counting */
1435 enable_irq(ROCON_RX_IRQn); /* Enable interrupt */
1442 pxmc_rocon_pwm_master_setup(unsigned lxpwr_chips)
1448 unsigned receiver_done_div = 1;
1449 unsigned lxpwr_chips_max = 2;
1450 #ifdef LXPWR_WITH_SIROLADC
1451 unsigned lxpwr_header = 1;
1452 unsigned lxpwr_words = 1 + 8 * 2 + 2;
1453 unsigned lxpwr_chip_pwm_cnt = 8;
1454 #else /*LXPWR_WITH_SIROLADC*/
1455 unsigned lxpwr_header = 0;
1456 unsigned lxpwr_words = 8;
1457 unsigned lxpwr_chip_pwm_cnt = 8;
1458 #endif /*LXPWR_WITH_SIROLADC*/
1460 #ifdef PXMC_ROCON_TIMED_BY_RX_DONE
1461 receiver_done_div = 5;
1462 #endif /*PXMC_ROCON_TIMED_BY_RX_DONE*/
1464 *fpga_lx_master_reset = 1;
1465 *fpga_lx_master_transmitter_reg = 0;
1466 *fpga_lx_master_transmitter_cycle = PXMC_LXPWR_PWM_CYCLE; /* 50 MHz -> 20 kHz */
1467 *fpga_lx_master_receiver_done_div = receiver_done_div << 8;
1468 pxmc_rocon_rx_done_sqn_inc = receiver_done_div;
1470 if (lxpwr_chips > lxpwr_chips_max)
1473 for (i = 0; i < LX_MASTER_DATA_OFFS + lxpwr_words * lxpwr_chips_max; i++)
1474 fpga_lx_master_receiver_base[i] = 0;
1476 if (lxpwr_chips >= 2) {
1477 word_slot = LX_MASTER_DATA_OFFS + lxpwr_words;
1478 fpga_lx_master_receiver_base[grp_in++] = (word_slot << 8) | lxpwr_words;
1481 word_slot = LX_MASTER_DATA_OFFS;
1482 fpga_lx_master_receiver_base[grp_in++] = (word_slot << 8) | lxpwr_words;
1484 fpga_lx_master_receiver_base[grp_in++] = 0x0000;
1486 for (i = 0; i < LX_MASTER_DATA_OFFS + lxpwr_words * lxpwr_chips_max; i++)
1487 fpga_lx_master_transmitter_base[i] = 0;
1489 word_slot = LX_MASTER_DATA_OFFS + lxpwr_header + lxpwr_chip_pwm_cnt;
1490 fpga_lx_master_transmitter_base[grp_out++] = (word_slot << 8) | lxpwr_words;
1491 #ifdef LXPWR_WITH_SIROLADC
1492 fpga_lx_master_transmitter_base[word_slot] = 0xc100 | (lxpwr_words - 1);
1493 #endif /*LXPWR_WITH_SIROLADC*/
1495 word_slot = LX_MASTER_DATA_OFFS + 0;
1496 fpga_lx_master_transmitter_base[grp_out++] = (word_slot << 8) | lxpwr_words;
1497 #ifdef LXPWR_WITH_SIROLADC
1498 fpga_lx_master_transmitter_base[word_slot] = 0xc100 | (lxpwr_words - 1);
1499 #endif /*LXPWR_WITH_SIROLADC*/
1501 fpga_lx_master_transmitter_base[grp_out++] = 0x0000;
1503 *fpga_lx_master_reset = 0;
1504 *fpga_lx_master_transmitter_cycle = PXMC_LXPWR_PWM_CYCLE; /* 50 MHz -> 20 kHz */
1505 *fpga_lx_master_receiver_done_div = receiver_done_div << 8;
1511 pxmc_rocon_wait_rx_done(void)
1515 uint32_t timeout = 10000;
1517 sqn_last = *fpga_lx_master_receiver_done_div;
1518 sqn_last = sqn_last & 0x1f;
1521 sqn_act = *fpga_lx_master_receiver_done_div;
1522 sqn_act = sqn_act & 0x1f;
1523 if (sqn_act != sqn_last)
1531 pxmc_rocon_pwm_master_init(void)
1534 volatile uint32_t *lxpwr_header_ptr;
1535 unsigned lxpwr_words = 1 + 8 * 2 + 2;
1537 pxmc_rocon_lxpwr_chips = 0;
1539 res = pxmc_rocon_pwm_master_setup(2);
1543 if (pxmc_rocon_wait_rx_done() < 0)
1545 if (pxmc_rocon_wait_rx_done() < 0)
1548 lxpwr_header_ptr = fpga_lx_master_receiver_base;
1549 lxpwr_header_ptr += LX_MASTER_DATA_OFFS;
1551 if (lxpwr_header_ptr[0] == 0xb100 + lxpwr_words - 1) {
1552 if (lxpwr_header_ptr[lxpwr_words] == 0xb100 + lxpwr_words - 1) {
1553 pxmc_rocon_lxpwr_chips = 2;
1559 if (lxpwr_header_ptr[lxpwr_words] != 0xb100 + lxpwr_words - 1) {
1563 res = pxmc_rocon_pwm_master_setup(1);
1567 if (pxmc_rocon_wait_rx_done() < 0)
1569 if (pxmc_rocon_wait_rx_done() < 0)
1572 if (lxpwr_header_ptr[0] != 0xb100 + lxpwr_words - 1)
1575 pxmc_rocon_lxpwr_chips = 1;
1580 int pxmc_ptofs_from_index(pxmc_state_t *mcs, unsigned long irc,
1581 unsigned long index_irc, int diff2err)
1586 ofs = ofsl = index_irc - mcs->pxms_ptmark;
1590 diff = (unsigned short)ofs - (unsigned short)mcs->pxms_ptofs;
1591 if (diff >= mcs->pxms_ptirc / 2)
1592 diff -= mcs->pxms_ptirc;
1593 if (diff <= -mcs->pxms_ptirc / 2)
1594 diff += mcs->pxms_ptirc;
1597 if(diff >= mcs->pxms_ptirc / 6) {
1602 diff = (unsigned long)ofsl - irc;
1603 ofs = ofsl - (diff / mcs->pxms_ptirc) * mcs->pxms_ptirc;
1606 mcs->pxms_ptofs = ofs;
1612 * pxmc_dummy_con - Dummy controller for synchronous BLDC/PMSM/steper drive
1613 * @mcs: Motion controller state information
1616 pxmc_dummy_con(pxmc_state_t *mcs)
1621 int pxmc_rocon_hh_gd10(pxmc_state_t *mcs);
1622 int pxmc_rocon_hh_gd20(pxmc_state_t *mcs);
1623 int pxmc_rocon_hh_gd30(pxmc_state_t *mcs);
1624 int pxmc_rocon_hh_gd40(pxmc_state_t *mcs);
1625 int pxmc_rocon_hh_gd50(pxmc_state_t *mcs);
1626 int pxmc_rocon_hh_gd90(pxmc_state_t *mcs);
1628 /* initialize for hard home */
1630 pxmc_rocon_hh_gi(pxmc_state_t *mcs)
1632 pxmc_set_flag(mcs,PXMS_BSY_b);
1633 #if 0 /* config and speed already set in pxmc_hh */
1635 spd >>= mcs->pxms_cfg & PXMS_CFG_HSPD_m;
1637 if(mcs->pxms_cfg & PXMS_CFG_HDIR_m)
1639 mcs->pxms_gen_hsp = spd;
1642 mcs->pxms_gen_htim = 16;
1643 mcs->pxms_do_gen = pxmc_rocon_hh_gd10;
1644 return pxmc_rocon_hh_gd10(mcs);
1647 /* fill initial mark filter and then decide */
1649 pxmc_rocon_hh_gd10(pxmc_state_t *mcs)
1653 if(mcs->pxms_flg & PXMS_ERR_m)
1654 return pxmc_spdnext_gend(mcs);
1656 pxmc_spd_gacc(&(mcs->pxms_rs), 0, mcs->pxms_ma);
1657 mcs->pxms_rp += mcs->pxms_rs;
1659 mark = pxmc_inp_rocon_is_mark(mcs);
1661 if (mcs->pxms_gen_htim) {
1662 mcs->pxms_gen_htim--;
1666 if (!(mcs->pxms_cfg & PXMS_CFG_HLS_m)) {
1667 /* limit switch is not used */
1668 pxmc_inp_rocon_is_index_edge(mcs);
1669 mcs->pxms_do_gen = pxmc_rocon_hh_gd50;
1674 /* go out from switch */
1675 mcs->pxms_do_gen = pxmc_rocon_hh_gd20;
1677 /* switch is off -> look for it */
1678 mcs->pxms_do_gen = pxmc_rocon_hh_gd30;
1683 /* go out from switch */
1685 pxmc_rocon_hh_gd20(pxmc_state_t *mcs)
1689 if(mcs->pxms_flg & PXMS_ERR_m)
1690 return pxmc_spdnext_gend(mcs);
1692 mark = pxmc_inp_rocon_is_mark(mcs);
1695 /* switch is off -> look for it again */
1696 mcs->pxms_do_gen = pxmc_rocon_hh_gd30;
1699 pxmc_spd_gacc(&(mcs->pxms_rs), -mcs->pxms_gen_hsp, mcs->pxms_ma);
1700 mcs->pxms_rp += mcs->pxms_rs;
1705 /* switch is off -> look for it */
1707 pxmc_rocon_hh_gd30(pxmc_state_t *mcs)
1712 if (mcs->pxms_flg & PXMS_ERR_m)
1713 return pxmc_spdnext_gend(mcs);
1715 pxmc_spd_gacc(&(mcs->pxms_rs), mcs->pxms_gen_hsp, mcs->pxms_ma);
1716 mcs->pxms_rp += mcs->pxms_rs;
1718 mark = pxmc_inp_rocon_is_mark(mcs);
1721 spd = mcs->pxms_gen_hsp >> 2; /* slow down */
1724 mcs->pxms_gen_hsp = spd;
1725 mcs->pxms_do_gen = pxmc_rocon_hh_gd40;
1731 /* switch is on -> find edge */
1733 pxmc_rocon_hh_gd40(pxmc_state_t *mcs)
1737 if (mcs->pxms_flg & PXMS_ERR_m)
1738 return pxmc_spdnext_gend(mcs);
1740 mark = pxmc_inp_rocon_is_mark(mcs);
1743 if (mcs->pxms_cfg & PXMS_CFG_HRI_m) {
1744 pxmc_inp_rocon_is_index_edge(mcs);
1745 mcs->pxms_do_gen = pxmc_rocon_hh_gd50;
1747 pxmc_inp_rocon_ap_zero(mcs);
1748 mcs->pxms_do_gen = pxmc_stop_gi;
1752 pxmc_spd_gacc(&(mcs->pxms_rs), -mcs->pxms_gen_hsp, mcs->pxms_ma);
1753 mcs->pxms_rp += mcs->pxms_rs;
1758 /* calibrate on revolution index */
1760 pxmc_rocon_hh_gd50(pxmc_state_t *mcs)
1762 if (mcs->pxms_flg & PXMS_ERR_m)
1763 return pxmc_spdnext_gend(mcs);
1765 pxmc_spd_gacc(&(mcs->pxms_rs), mcs->pxms_gen_hsp, mcs->pxms_ma);
1766 mcs->pxms_rp += mcs->pxms_rs;
1768 if (pxmc_inp_rocon_is_index_edge(mcs)){
1769 pxmc_inp_rocon_irc_offset_from_index(mcs);
1770 mcs->pxms_do_gen = pxmc_stop_gi;
1776 pxmc_call_t *pxmc_get_hh_gi_4axis(pxmc_state_t *mcs)
1778 return pxmc_rocon_hh_gi;
1781 pxmc_rocon_state_t mcs0 =
1789 pxmc_pid_con /*pxmc_dummy_con*/,
1791 pxmc_rocon_pwm_dc_out /*pxmc_rocon_pwm3ph_out*/,
1795 pxmc_inp_rocon_ap2hw,
1796 pxms_ap: 0, pxms_as: 0,
1797 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1798 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
1801 pxms_ene: 0, pxms_erc: 0,
1802 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1803 pxms_me: 0x7e00/*0x7fff*/,
1805 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m * 0 |
1806 PXMS_CFG_HRI_m * 0 | PXMS_CFG_HDIR_m * 0 |
1807 PXMS_CFG_I2PT_m * 0 | 0x2,
1812 /*pxms_ptamp: 0x7fff,*/
1823 pxmc_rocon_state_t mcs1 =
1833 pxmc_rocon_pwm_dc_out,
1837 pxmc_inp_rocon_ap2hw,
1838 pxms_ap: 0, pxms_as: 0,
1839 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1840 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
1843 pxms_ene: 0, pxms_erc: 0,
1844 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1845 pxms_me: 0x7e00/*0x7fff*/,
1847 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m * 0 |
1848 PXMS_CFG_HRI_m * 0 | PXMS_CFG_HDIR_m * 0 |
1849 PXMS_CFG_I2PT_m * 0 | 0x2,
1853 /*pxms_ptamp: 0x7fff,*/
1858 pxmc_rocon_state_t mcs2 =
1868 pxmc_rocon_pwm_dc_out,
1872 pxmc_inp_rocon_ap2hw,
1873 pxms_ap: 0, pxms_as: 0,
1874 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1875 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
1878 pxms_ene: 0, pxms_erc: 0,
1879 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1880 pxms_me: 0x7e00/*0x7fff*/,
1882 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m * 0 |
1883 PXMS_CFG_I2PT_m * 0 | PXMS_CFG_HRI_m |
1884 PXMS_CFG_HDIR_m | 0x2,
1888 /*pxms_ptamp: 0x7fff,*/
1893 pxmc_rocon_state_t mcs3 =
1903 pxmc_rocon_pwm_dc_out,
1907 pxmc_inp_rocon_ap2hw,
1908 pxms_ap: 0, pxms_as: 0,
1909 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1910 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
1913 pxms_ene: 0, pxms_erc: 0,
1914 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1915 pxms_me: 0x7e00/*0x7fff*/,
1917 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m * 0 |
1918 PXMS_CFG_I2PT_m * 0 | PXMS_CFG_HRI_m |
1919 PXMS_CFG_HDIR_m * 0 | 0x2,
1923 /*pxms_ptamp: 0x7fff,*/
1928 pxmc_rocon_state_t mcs4 =
1938 pxmc_rocon_pwm_dc_out,
1942 pxmc_inp_rocon_ap2hw,
1943 pxms_ap: 0, pxms_as: 0,
1944 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1945 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
1948 pxms_ene: 0, pxms_erc: 0,
1949 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1950 pxms_me: 0x7e00/*0x7fff*/,
1952 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m * 0 |
1953 PXMS_CFG_HRI_m | PXMS_CFG_I2PT_m * 0 |
1954 PXMS_CFG_HDIR_m | 0x2,
1958 /*pxms_ptamp: 0x7fff,*/
1963 pxmc_rocon_state_t mcs5 =
1973 pxmc_rocon_pwm_dc_out,
1977 pxmc_inp_rocon_ap2hw,
1978 pxms_ap: 0, pxms_as: 0,
1979 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
1980 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
1983 pxms_ene: 0, pxms_erc: 0,
1984 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
1985 pxms_me: 0x7e00/*0x7fff*/,
1987 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m |
1988 PXMS_CFG_HRI_m | PXMS_CFG_I2PT_m * 0 |
1989 PXMS_CFG_HDIR_m | 0x2,
1993 /*pxms_ptamp: 0x7fff,*/
1998 pxmc_rocon_state_t mcs6 =
2008 pxmc_rocon_pwm_dc_out,
2012 pxmc_inp_rocon_ap2hw,
2013 pxms_ap: 0, pxms_as: 0,
2014 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
2015 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
2018 pxms_ene: 0, pxms_erc: 0,
2019 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
2020 pxms_me: 0x7e00/*0x7fff*/,
2022 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_I2PT_m * 0 |
2027 /*pxms_ptamp: 0x7fff,*/
2032 pxmc_rocon_state_t mcs7 =
2042 pxmc_rocon_pwm_dc_out,
2046 pxmc_inp_rocon_ap2hw,
2047 pxms_ap: 0, pxms_as: 0,
2048 pxms_rp: 55 * 256, pxms_rs: 0, pxms_subdiv: 8,
2049 pxms_md: 800 << 8, pxms_ms: 500, pxms_ma: 10,
2052 pxms_ene: 0, pxms_erc: 0,
2053 pxms_p: 80, pxms_i: 10, pxms_d: 200, pxms_s1: 200, pxms_s2: 0,
2054 pxms_me: 0x7e00/*0x7fff*/,
2056 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_I2PT_m * 0 |
2061 /*pxms_ptamp: 0x7fff,*/
2066 pxmc_state_t *pxmc_main_arr[PXML_MAIN_CNT] =
2067 {&mcs0.base, &mcs1.base, &mcs2.base, &mcs3.base,
2068 &mcs4.base, &mcs5.base, &mcs6.base, &mcs7.base};
2071 pxmc_state_list_t pxmc_main_list =
2078 void pxmc_lpc_qei_callback_index(struct lpc_qei_state_t *qst, void *context)
2080 pxmc_state_t *mcs = (pxmc_state_t *)context;
2083 irc = qst->index_pos;
2085 if ((mcs->pxms_cfg & PXMS_CFG_I2PT_m) && (mcs->pxms_flg & PXMS_PTI_m))
2088 ofs = irc - mcs->pxms_ptmark;
2089 diff = ofs - mcs->pxms_ptofs;
2091 if (diff >= mcs->pxms_ptirc / 2)
2092 diff -= mcs->pxms_ptirc;
2094 if (diff <= -mcs->pxms_ptirc / 2)
2095 diff += mcs->pxms_ptirc;
2100 if (diff >= mcs->pxms_ptirc / 6)
2102 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
2106 mcs->pxms_ptofs = ofs;
2107 pxmc_set_flag(mcs, PXMS_PHA_b);
2111 ofs=irc-mcs->pxms_ptofs;
2112 if((unsigned short)ofs>=(unsigned short)mcs->pxms_ptirc) {
2114 ofs-=mcs->pxms_ptirc;
2116 ofs+=mcs->pxms_ptirc;
2119 mcs->pxms_ptmark=ofs;
2122 /*lpc_qei_set_cmpos(qst, 0, qst->index_pos-4000);*/
2125 int pxmc_lpc_pthalalign_callback(pxmc_state_t *mcs)
2129 lpc_qei_state_t *qst = &lpc_qei_state;
2130 int irc = lpc_qei_get_pos(qst);
2133 if (!qst->index_occ)
2136 idx_rel = qst->index_pos - irc;
2137 idx_rel %= mcs->pxms_ptirc;
2140 idx_rel += mcs->pxms_ptirc;
2142 ptofs = irc - mcs->pxms_ptofs;
2143 ptmark = ptofs + idx_rel;
2145 if ((unsigned short)ptmark >= mcs->pxms_ptirc)
2148 ptmark -= mcs->pxms_ptirc;
2150 ptmark += mcs->pxms_ptirc;
2153 if ((unsigned short)ptmark < mcs->pxms_ptirc)
2155 mcs->pxms_ptmark = ptmark;
2161 int pxmc_lpc_pthalalign(pxmc_state_t *mcs, int periods)
2166 pxmc_call_t *fin_fnc = pxmc_lpc_pthalalign_callback;
2167 lpc_qei_state_t *qst = &lpc_qei_state;
2169 mcs->pxms_cfg &= ~PXMS_CFG_I2PT_m;
2170 lpc_qei_setup_index_catch(qst);
2172 r2acq = ((long)mcs->pxms_ptirc << PXMC_SUBDIV(mcs)) * periods;
2173 spd = 1 << PXMC_SUBDIV(mcs);
2175 res = pxmc_pthalalign(mcs, r2acq, spd, fin_fnc);
2180 int pxmc_lpc_pthalalign_run(void)
2182 return pxmc_lpc_pthalalign(pxmc_main_list.pxml_arr[0], 20);
2185 static inline void pxmc_sfi_input(void)
2189 pxmc_for_each_mcs(var, mcs)
2191 /* PXMS_ENI_m - check if input (IRC) update is enabled */
2192 if (mcs->pxms_flg & PXMS_ENI_m)
2194 pxmc_call(mcs, mcs->pxms_do_inp);
2199 static inline void pxmc_sfi_controller_and_output(void)
2203 pxmc_for_each_mcs(var, mcs)
2205 /* PXMS_ENR_m - check if controller is enabled */
2206 if (mcs->pxms_flg & PXMS_ENR_m || mcs->pxms_flg & PXMS_ENO_m)
2209 /* If output only is enabled, we skip the controller */
2210 if (mcs->pxms_flg & PXMS_ENR_m)
2213 pxmc_call(mcs, mcs->pxms_do_con);
2215 /* PXMS_ERR_m - if axis in error state */
2216 if (mcs->pxms_flg & PXMS_ERR_m)
2220 /* for bushless motors, it is necessary to call do_out
2221 even if the controller is not enabled and PWM should be provided. */
2222 pxmc_call(mcs, mcs->pxms_do_out);
2227 static inline void pxmc_sfi_generator(void)
2231 pxmc_for_each_mcs(var, mcs)
2233 /* PXMS_ENG_m - check if requested value (position) generator is enabled */
2234 if (mcs->pxms_flg & PXMS_ENG_m)
2236 pxmc_call(mcs, mcs->pxms_do_gen);
2241 static inline void pxmc_sfi_dbg(void)
2245 pxmc_for_each_mcs(var, mcs)
2247 if (mcs->pxms_flg & PXMS_DBG_m)
2249 pxmc_call(mcs, mcs->pxms_do_deb);
2254 int pxmc_rocon_pthalalign_callback(pxmc_state_t *mcs)
2258 int inp_chan = mcs->pxms_inp_info;
2260 long irc = fpga_irc[inp_chan]->count;
2262 if (!pxmc_inp_rocon_is_index_edge(mcs))
2265 idx_rel = fpga_irc[inp_chan]->count_index - irc;
2266 idx_rel %= mcs->pxms_ptirc;
2268 idx_rel += mcs->pxms_ptirc;
2270 ptofs = irc-mcs->pxms_ptofs;
2271 ptmark = ptofs+idx_rel;
2273 if((unsigned short)ptmark >= mcs->pxms_ptirc) {
2275 ptmark -= mcs->pxms_ptirc;
2277 ptmark += mcs->pxms_ptirc;
2280 if((unsigned short)ptmark < mcs->pxms_ptirc) {
2281 mcs->pxms_ptmark = ptmark;
2286 int pxmc_rocon_pthalalign(pxmc_state_t *mcs, int periods)
2291 pxmc_call_t *fin_fnc = pxmc_rocon_pthalalign_callback;
2293 mcs->pxms_cfg&=~PXMS_CFG_I2PT_m;
2295 r2acq=((long)mcs->pxms_ptirc<<PXMC_SUBDIV(mcs))*periods;
2296 spd=1<<PXMC_SUBDIV(mcs);
2298 /* clear bit indicating previous index */
2299 pxmc_inp_rocon_is_index_edge(mcs);
2301 res=pxmc_pthalalign(mcs, r2acq, spd, fin_fnc);
2306 int pxmc_axis_out_chans4mode(int mode)
2309 case PXMC_AXIS_MODE_DC:
2311 case PXMC_AXIS_MODE_BLDC:
2312 case PXMC_AXIS_MODE_BLDC_PXMCC:
2314 case PXMC_AXIS_MODE_STEPPER_WITH_IRC:
2315 case PXMC_AXIS_MODE_STEPPER_WITH_IRC_PXMCC:
2316 case PXMC_AXIS_MODE_STEPPER_PXMCC:
2322 int pxmc_axis_rdmode(pxmc_state_t *mcs)
2324 if (mcs->pxms_do_out == pxmc_rocon_pwm2ph_out)
2325 return PXMC_AXIS_MODE_STEPPER_WITH_IRC;
2326 if (mcs->pxms_do_out == pxmc_rocon_pwm_dc_out)
2327 return PXMC_AXIS_MODE_DC;
2328 if (mcs->pxms_do_out == pxmc_rocon_pwm3ph_out)
2329 return PXMC_AXIS_MODE_BLDC;
2330 if (mcs->pxms_do_out == pxmc_pxmcc_pwm3ph_out)
2331 return PXMC_AXIS_MODE_BLDC_PXMCC;
2332 if (mcs->pxms_do_out == pxmc_pxmcc_pwm2ph_out)
2333 return PXMC_AXIS_MODE_STEPPER_WITH_IRC_PXMCC;
2334 if (mcs->pxms_do_out == pxmc_pxmcc_nofb2ph_out)
2335 return PXMC_AXIS_MODE_STEPPER_PXMCC;
2340 pxmc_axis_pt4mode(pxmc_state_t *mcs, int mode)
2342 static const typeof(*mcs->pxms_ptptr1) dummy0 = 0;
2345 if (mode == PXMC_AXIS_MODE_NOCHANGE)
2346 mode = pxmc_axis_rdmode(mcs);
2351 /* case PXMC_AXIS_MODE_STEPPER: */
2352 case PXMC_AXIS_MODE_STEPPER_PXMCC:
2353 case PXMC_AXIS_MODE_STEPPER_WITH_IRC:
2354 case PXMC_AXIS_MODE_STEPPER_WITH_IRC_PXMCC:
2355 res = pxmc_ptable_set_profile(mcs, &pxmc_ptprofile_sin, 0, 0);
2357 /*case PXMC_AXIS_MODE_STEPPER_WITH_PWM:*/
2358 case PXMC_AXIS_MODE_DC:
2359 /*profive some sane dummy values*/
2360 mcs->pxms_ptptr1 = (typeof(mcs->pxms_ptptr1))&dummy0;
2361 mcs->pxms_ptptr2 = (typeof(mcs->pxms_ptptr1))&dummy0;
2362 mcs->pxms_ptptr3 = (typeof(mcs->pxms_ptptr1))&dummy0;
2364 mcs->pxms_ptscale_mult=1;
2365 mcs->pxms_ptscale_shift=15;
2367 case PXMC_AXIS_MODE_BLDC:
2368 case PXMC_AXIS_MODE_BLDC_PXMCC:
2369 /* res = pxmc_init_ptable(mcs, PXMC_PTPROF_SIN3FUP); */
2370 #ifndef PXMC_WITH_PT_ZIC
2371 res = pxmc_ptable_set_profile(mcs, &pxmc_ptprofile_sin3phup, 0, 0);
2372 #else /*PXMC_WITH_PT_ZIC*/
2373 res = pxmc_ptable_set_profile(mcs, &pxmc_ptprofile_sin3phup_zic, 0, 0);
2374 #endif /*PXMC_WITH_PT_ZIC*/
2380 mcs->pxms_ptvang = pxmc_ptvang_deg2irc(mcs, 90);
2386 * pxmc_axis_mode - Sets axis mode.[extern API]
2387 * @mcs: Motion controller state information
2388 * @mode: 0 .. previous mode, 1 .. stepper motor mode,
2389 * 2 .. stepper motor with IRC feedback and PWM ,
2390 * 3 .. stepper motor with PWM control
2391 * 4 .. DC motor with IRC feedback and PWM
2395 pxmc_axis_mode(pxmc_state_t *mcs, int mode)
2400 pxmc_axis_release(mcs);
2401 pxmc_clear_flag(mcs, PXMS_ENI_b);
2402 pxmc_clear_flags(mcs,PXMS_ENO_m);
2403 /* Clear possible stall index flags from hardware */
2404 pxmc_inp_rocon_is_index_edge(mcs);
2405 pxmc_clear_flag(mcs, PXMS_PHA_b);
2406 pxmc_clear_flag(mcs, PXMS_PTI_b);
2409 prev_mode = pxmc_axis_rdmode(mcs);
2411 if (mode == PXMC_AXIS_MODE_NOCHANGE)
2416 mode = PXMC_AXIS_MODE_DC;
2418 if ((prev_mode == PXMC_AXIS_MODE_BLDC_PXMCC) ||
2419 (prev_mode == PXMC_AXIS_MODE_STEPPER_WITH_IRC_PXMCC) ||
2420 (prev_mode == PXMC_AXIS_MODE_STEPPER_PXMCC))
2421 pxmcc_axis_setup(mcs, PXMCC_MODE_IDLE);
2423 res = pxmc_axis_pt4mode(mcs, mode);
2427 if (mcs->pxms_do_inp == pxmc_pxmcc_nofb2ph_inp)
2428 mcs->pxms_do_inp = pxmc_inp_rocon_inp;
2429 if (mcs->pxms_do_con == pxmc_pxmcc_nofb_con)
2430 mcs->pxms_do_con = pxmc_pid_con;
2433 /*case PXMC_AXIS_MODE_STEPPER:*/
2434 case PXMC_AXIS_MODE_STEPPER_WITH_IRC:
2435 mcs->pxms_do_out = pxmc_rocon_pwm2ph_out;
2437 /*case PXMC_AXIS_MODE_STEPPER_WITH_PWM:*/
2438 case PXMC_AXIS_MODE_DC:
2439 mcs->pxms_do_out = pxmc_rocon_pwm_dc_out;
2441 case PXMC_AXIS_MODE_BLDC:
2442 mcs->pxms_do_out = pxmc_rocon_pwm3ph_out;
2444 case PXMC_AXIS_MODE_BLDC_PXMCC:
2445 if (pxmcc_axis_setup(mcs, PXMCC_MODE_BLDC) < 0)
2447 pxmcc_axis_enable(mcs, 1);
2448 mcs->pxms_do_out = pxmc_pxmcc_pwm3ph_out;
2450 case PXMC_AXIS_MODE_STEPPER_WITH_IRC_PXMCC:
2451 if (pxmcc_axis_setup(mcs, PXMCC_MODE_STEPPER_WITH_IRC) < 0)
2453 pxmcc_axis_enable(mcs, 1);
2454 mcs->pxms_do_out = pxmc_pxmcc_pwm2ph_out;
2456 case PXMC_AXIS_MODE_STEPPER_PXMCC:
2457 if (pxmcc_axis_setup(mcs, PXMCC_MODE_STEPPER) < 0)
2459 pxmcc_axis_enable(mcs, 1);
2460 mcs->pxms_do_inp = pxmc_pxmcc_nofb2ph_inp;
2461 mcs->pxms_do_con = pxmc_pxmcc_nofb_con;
2462 mcs->pxms_do_out = pxmc_pxmcc_nofb2ph_out;
2468 /* Clear possible stall index flags from hardware */
2469 pxmc_inp_rocon_is_index_edge(mcs);
2470 /* Request new phases alignment for changed parameters */
2471 pxmc_clear_flag(mcs, PXMS_PHA_b);
2472 pxmc_clear_flag(mcs, PXMS_PTI_b);
2473 pxmc_set_flag(mcs, PXMS_ENI_b);
2477 void pxmc_sfi_isr(void)
2479 unsigned long spent = pxmc_fast_tick_time();
2482 pxmc_sfi_controller_and_output();
2483 pxmc_sfi_generator();
2485 /* Kick LX Master watchdog */
2486 if (pxmc_main_list.pxml_cnt != 0)
2487 *fpga_lx_master_transmitter_wdog = 1;
2489 spent = pxmc_fast_tick_time() - spent;
2491 if(spent > pxmc_sfi_spent_time_max)
2492 pxmc_sfi_spent_time_max = spent;
2496 int pxmc_clear_power_stop(void)
2501 int pxmc_process_state_check(unsigned long *pbusy_bits,
2502 unsigned long *perror_bits)
2505 unsigned short chan;
2506 unsigned long busy_bits = 0;
2507 unsigned long error_bits = 0;
2510 pxmc_for_each_mcs(chan, mcs) {
2512 flg |= mcs->pxms_flg;
2513 if (mcs->pxms_flg & PXMS_BSY_m)
2514 busy_bits |= 1 << chan;
2515 if (mcs->pxms_flg & PXMS_ERR_m)
2516 error_bits |= 1 << chan;
2519 if (appl_errstop_mode) {
2520 if((flg & PXMS_ENG_m) && (flg & PXMS_ERR_m)) {
2521 pxmc_for_each_mcs(chan, mcs) {
2522 if(mcs&&(mcs->pxms_flg & PXMS_ENG_m)) {
2529 if (pbusy_bits != NULL)
2530 *pbusy_bits = busy_bits;
2531 if (error_bits != NULL)
2532 *perror_bits = error_bits;
2542 if (!pxmc_main_list.pxml_cnt)
2545 pxmc_for_each_mcs(var, mcs)
2547 pxmc_axis_release(mcs);
2550 pxmc_main_list.pxml_cnt = 0;
2556 int pxmc_initialize(void)
2561 pxmc_main_list.pxml_cnt = 0;
2562 pxmc_dbg_hist = NULL;
2563 #ifdef PXMC_ROCON_TIMED_BY_RX_DONE
2564 disable_irq(ROCON_RX_IRQn);
2565 #endif /*PXMC_ROCON_TIMED_BY_RX_DONE*/
2568 pxmc_state_t *mcs = &mcs0.base;
2569 lpc_qei_state_t *qst = &lpc_qei_state;
2571 *fpga_irc_reset = 1;
2573 for (i = 0; i < 8; i++) {
2574 fpga_irc[i]->count = 0;
2575 fpga_irc[i]->count_index = 0;
2576 *fpga_irc_state[i] = FPGA_IRC_STATE_INDEX_EVENT_MASK;
2579 /* Initialize QEI module for IRC counting */
2580 pxmc_inp_lpc_qei_init(mcs->pxms_inp_info);
2582 /* Initialize QEI events processing */
2583 if (lpc_qei_setup_irq(qst) < 0)
2586 *fpga_irc_reset = 0;
2588 //res = pxmc_axis_pt4mode(mcs, PXMC_AXIS_MODE_BLDC);
2590 /*pxmc_ctm4pwm3f_wr(mcs, 0, 0, 0);*/
2591 //pxmc_rocon_pwm3ph_wr(mcs, 0, 0, 0);
2593 res = pxmc_rocon_pwm_master_init();
2597 #ifdef PXMC_ROCON_TIMED_BY_RX_DONE
2598 pxmc_rocon_rx_done_isr_setup(pxmc_rocon_rx_done_isr);
2599 #endif /*PXMC_ROCON_TIMED_BY_RX_DONE*/
2602 pxmc_main_list.pxml_cnt = PXML_MAIN_CNT;