1 /*******************************************************************
2 Motion and Robotic System (MARS) aplication components.
4 appl_pxmc.c - SPI connected motor control board specific
7 Copyright (C) 2001-2015 by Pavel Pisa - originator
9 (C) 2001-2015 by PiKRON Ltd. - originator
12 This file can be used and copied according to next
14 - GPL - GNU Public License
15 - other license provided by project originators
17 *******************************************************************/
20 #include <system_def.h>
22 #include <pxmc_internal.h>
23 #include <pxmc_inp_common.h>
24 #include <pxmc_gen_info.h>
25 #include <pxmc_dq_trans.h>
26 #include <pxmc_sin_fixed.h>
30 #if !defined(clzl) && !defined(HAVE_CLZL)
31 #define clzl __builtin_clzl
34 #include "appl_defs.h"
35 #include "appl_pxmc.h"
36 #include "appl_utils.h"
38 #ifdef APPL_WITH_ZYNQ_DRV
39 #include "zynq_3pmdrv1_mc.h"
40 typedef z3pmdrv1_state_t spimc_state_t;
41 #define SPIMC_PWM_ENABLE Z3PMDRV1_PWM_ENABLE
42 #define SPIMC_PWM_SHUTDOWN Z3PMDRV1_PWM_SHUTDOWN
43 #define SPIMC_CHAN_COUNT Z3PMDRV1_CHAN_COUNT
44 #define spimc_transfer z3pmdrv1_transfer
45 #define spimc_init z3pmdrv1_init
47 #include "pxmc_spimc.h"
50 pthread_t pxmc_base_thread_id;
52 int pxmc_ptofs_from_index(pxmc_state_t *mcs, unsigned long irc,
53 unsigned long index_irc, int diff2err);
55 #define PXML_MAIN_CNT 1
57 #undef PXMC_WITH_PT_ZIC
58 #define PXMC_PT_ZIC_MASK 0x8000
60 #define HAL_ERR_SENSITIVITY 20
61 #define HAL_ERR_MAX_COUNT 5
63 #define PXMC_LXPWR_PWM_CYCLE 2048
65 unsigned pxmc_spimc_pwm_magnitude = PXMC_LXPWR_PWM_CYCLE;
67 unsigned pxmc_spimc_mark_filt[PXML_MAIN_CNT];
68 unsigned pxmc_spimc_lxpwr_chips = 0;
69 int appl_errstop_mode = 0;
72 pxmc_spimc_state_t *pxmc_state2spimc_state(pxmc_state_t *mcs)
74 pxmc_spimc_state_t *mcsrc;
76 mcsrc = UL_CONTAINEROF(mcs, pxmc_spimc_state_t, base);
77 #else /*UL_CONTAINEROF*/
78 mcsrc = (pxmc_spimc_state_t*)((char*)mcs - __builtin_offsetof(pxmc_spimc_state_t, base));
79 #endif /*UL_CONTAINEROF*/
83 const uint8_t onesin10bits[1024]={
84 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,
85 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
86 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,
87 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,
88 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,
89 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
90 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,
91 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,
92 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,
93 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
94 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,
95 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,
96 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,
97 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
98 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,
99 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,
100 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,
101 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
102 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,
103 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,
104 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,
105 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
106 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,
107 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,
108 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,
109 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
110 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,
111 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,
112 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,
113 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,
114 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,
115 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
119 pxmc_inp_spimc_inp(struct pxmc_state *mcs)
121 pxmc_spimc_state_t *mcsrc = pxmc_state2spimc_state(mcs);
122 int chan=mcs->pxms_inp_info;
126 /* read position from hardware */
127 irc = mcsrc->spimc_state->act_pos;
128 irc += mcsrc->spimc_state->pos_offset;
129 pos = irc << PXMC_SUBDIV(mcs);
130 mcs->pxms_as = pos - mcs->pxms_ap;
133 /* Running of the motor commutator */
134 if (mcs->pxms_flg & PXMS_PTI_m)
135 pxmc_irc_16bit_commindx(mcs, irc);
141 pxmc_inp_spimc_ap2hw(struct pxmc_state *mcs)
143 pxmc_spimc_state_t *mcsrc = pxmc_state2spimc_state(mcs);
144 int chan=mcs->pxms_inp_info;
148 irc = mcsrc->spimc_state->act_pos;
149 pos_diff = mcs->pxms_ap - (irc << PXMC_SUBDIV(mcs));
151 irc = pos_diff >> PXMC_SUBDIV(mcs);
153 /* Adjust phase table alignemt to modified IRC readout */
154 mcs->pxms_ptofs += irc - mcsrc->spimc_state->pos_offset;
156 mcsrc->spimc_state->pos_offset = irc;
161 pxmc_spimc_bldc_hal_rd(pxmc_state_t *mcs)
163 pxmc_spimc_state_t *mcsrc = pxmc_state2spimc_state(mcs);
165 int chan = mcs->pxms_out_info;
167 h = mcsrc->spimc_state->hal_sensors;
169 /* return 3 bits corresponding to the HAL senzor input */
174 const unsigned char pxmc_lpc_bdc_hal_pos_table[8] =
186 const unsigned char pxmc_lpc_bdc_hal_pos_table[8] =
199 int pxmc_spimc_pwm_direct_wr(unsigned chan, unsigned pwm, int en)
206 * pxmc_spimc_pwm3ph_wr - Output of the 3-phase PWM to the hardware
207 * @mcs: Motion controller state information
209 /*static*/ inline void
210 pxmc_spimc_pwm3ph_wr(pxmc_state_t *mcs, uint32_t pwm1, uint32_t pwm2, uint32_t pwm3)
212 pxmc_spimc_state_t *mcsrc = pxmc_state2spimc_state(mcs);
213 int chan = mcs->pxms_out_info;
215 mcsrc->spimc_state->pwm[0] = pwm1;
216 mcsrc->spimc_state->pwm[1] = pwm2;
217 mcsrc->spimc_state->pwm[2] = pwm3;
221 pxmc_spimc_process_hal_error(struct pxmc_state *mcs)
223 if (mcs->pxms_halerc >= HAL_ERR_SENSITIVITY * HAL_ERR_MAX_COUNT)
225 pxmc_set_errno(mcs, PXMS_E_HAL);
230 mcs->pxms_halerc += HAL_ERR_SENSITIVITY;
234 pxmc_inp_spimc_ptofs_from_index_poll(struct pxmc_state *mcs, int diff2err)
236 pxmc_spimc_state_t *mcsrc = pxmc_state2spimc_state(mcs);
237 int chan=mcs->pxms_inp_info;
244 irc = mcsrc->spimc_state->act_pos + mcsrc->spimc_state->pos_offset;
245 index_irc = mcsrc->spimc_state->index_pos + mcsrc->spimc_state->pos_offset;
247 return pxmc_ptofs_from_index(mcs, irc, index_irc, diff2err);
251 * pxmc_spimc_pwm3ph_out - Phase output for brush-less 3-phase motor
252 * @mcs: Motion controller state information
255 pxmc_spimc_pwm3ph_out(pxmc_state_t *mcs)
257 pxmc_spimc_state_t *mcsrc = pxmc_state2spimc_state(mcs);
258 typeof(mcs->pxms_ptvang) ptvang;
260 unsigned char hal_pos;
262 int32_t sin_val, cos_val;
263 int32_t pwm_d, pwm_q;
264 int32_t pwm_alp, pwm_bet;
265 uint32_t pwm1, pwm2, pwm3;
269 if (!(mcs->pxms_flg & PXMS_PTI_m) || !(mcs->pxms_flg & PXMS_PHA_m) ||
270 (mcs->pxms_flg & PXMS_PRA_m))
273 short ptirc = mcs->pxms_ptirc;
274 short divisor = mcs->pxms_ptper * 6;
276 hal_pos = pxmc_lpc_bdc_hal_pos_table[pxmc_spimc_bldc_hal_rd(mcs)];
281 pxmc_spimc_process_hal_error(mcs);
285 if (mcs->pxms_halerc)
288 ptindx = (hal_pos * ptirc + divisor / 2) / divisor;
290 if (!(mcs->pxms_flg & PXMS_PTI_m) || (mcs->pxms_flg & PXMS_PRA_m))
292 if (((hal_pos != mcs->pxms_hal) && (mcs->pxms_hal != 0x40)) && 1)
294 short ptindx_prev = (mcs->pxms_hal * ptirc + divisor / 2) / divisor;;
296 if ((ptindx > ptindx_prev + ptirc / 2) ||
297 (ptindx_prev > ptindx + ptirc / 2))
299 ptindx = (ptindx_prev + ptindx - ptirc) / 2;
306 ptindx = (ptindx_prev + ptindx) / 2;
309 mcs->pxms_ptindx = ptindx;
311 mcs->pxms_ptofs = (mcs->pxms_ap >> PXMC_SUBDIV(mcs)) + mcs->pxms_ptshift - ptindx;
313 pxmc_set_flag(mcs, PXMS_PTI_b);
314 pxmc_clear_flag(mcs, PXMS_PRA_b);
318 if (!(mcs->pxms_flg & PXMS_PTI_m))
319 mcs->pxms_ptindx = ptindx;
322 /* if phase table position to mask is know do fine phase table alignment */
323 if (mcs->pxms_cfg & PXMS_CFG_I2PT_m) {
325 res = pxmc_inp_spimc_ptofs_from_index_poll(mcs, 0);
327 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
329 pxmc_set_flag(mcs, PXMS_PTI_b);
330 pxmc_set_flag(mcs, PXMS_PHA_b);
334 mcs->pxms_hal = hal_pos;
339 /*wind_current[0]=(ADC->ADDR0 & 0xFFF0)>>4;*/
340 /* FIXME - check winding current against limit */
341 /* pxmc_set_errno(mcs, PXMS_E_WINDCURRENT); */
345 ptvang = mcs->pxms_ptvang;
347 pwm_q = mcs->pxms_ene;
350 pwm_d = mcs->pxms_flg & PXMS_BSY_m? mcs->pxms_me: 0;
354 if (pwm_d || pwm_q) {
356 uint32_t ptscale_mult = mcs->pxms_ptscale_mult |
357 (mcs->pxms_ptscale_shift << 16);
359 indx = mcs->pxms_ptindx;
362 pta = indx + mcs->pxms_ptirc;
368 pta -= PXMC_SIN_FIX_2PI3;
370 pxmc_sincos_fixed_inline(&sin_val, &cos_val, pta, 16);
371 pxmc_dq2alpbet(&pwm_alp, &pwm_bet, pwm_d, pwm_q, sin_val, cos_val);
372 pxmc_alpbet2pwm3ph(&pwm1, &pwm2, &pwm3, pwm_alp, pwm_bet);
374 /*printf("pwm d %4d q %4d alp %4d bet %4d a %4d b %4d c %4d\n",
375 pwm_d, pwm_q, pwm_alp >> 16, pwm_bet >> 16, pwm1, pwm2, pwm3);*/
378 #ifdef PXMC_WITH_PT_ZIC
379 if (labs(mcs->pxms_as) < (10 << PXMC_SUBDIV(mcs)))
382 #endif /*PXMC_WITH_PT_ZIC*/
384 /* Default phase-table amplitude is 0x7fff, ene max is 0x7fff */
385 /* Initialized CTM4 PWM period is 0x200 => divide by value about 2097024 */
387 unsigned long pwm_mag = pxmc_spimc_pwm_magnitude;
389 pwm1 = SPIMC_PWM_SHUTDOWN;
391 pwm1 = (((unsigned long long)pwm1 * pwm_mag) >> 15) | SPIMC_PWM_ENABLE;
393 pwm2 = SPIMC_PWM_SHUTDOWN;
395 pwm2 = (((unsigned long long)pwm2 * pwm_mag) >> 15) | SPIMC_PWM_ENABLE;
397 pwm3 = SPIMC_PWM_SHUTDOWN;
399 pwm3 = (((unsigned long long)pwm3 * pwm_mag) >> 15) | SPIMC_PWM_ENABLE;
401 pxmc_spimc_pwm3ph_wr(mcs, pwm1, pwm2, pwm3);
406 pxmc_spimc_pwm3ph_wr(mcs, 0, 0, 0);
409 /*printf("hal_pos %d pwm %4d %4d %4d\n", hal_pos, pwm1 & 0xffff,
410 pwm2 & 0xffff, pwm3 & 0xffff);*/
416 * pxmc_spimc_pwm_dc_out - DC motor CW and CCW PWM output
417 * @mcs: Motion controller state information
420 pxmc_spimc_pwm_dc_out(pxmc_state_t *mcs)
422 int chan = mcs->pxms_out_info;
423 int ene = mcs->pxms_ene;
429 ene = (ene * (pxmc_spimc_pwm_magnitude + 5)) >> 15;
430 pxmc_spimc_pwm3ph_wr(mcs, SPIMC_PWM_ENABLE, ene | SPIMC_PWM_ENABLE, 0);
434 ene = (ene * (pxmc_spimc_pwm_magnitude + 5)) >> 15;
435 pxmc_spimc_pwm3ph_wr(mcs, ene | SPIMC_PWM_ENABLE, SPIMC_PWM_ENABLE, 0);
441 int pxmc_ptofs_from_index(pxmc_state_t *mcs, unsigned long irc,
442 unsigned long index_irc, int diff2err)
447 ofs = ofsl = index_irc - mcs->pxms_ptmark;
451 diff = (unsigned short)ofs - (unsigned short)mcs->pxms_ptofs;
452 if (diff >= mcs->pxms_ptirc / 2)
453 diff -= mcs->pxms_ptirc;
454 if (diff <= -mcs->pxms_ptirc / 2)
455 diff += mcs->pxms_ptirc;
458 if(diff >= mcs->pxms_ptirc / 6) {
463 diff = (unsigned long)ofsl - irc;
464 ofs = ofsl - (diff / mcs->pxms_ptirc) * mcs->pxms_ptirc;
467 mcs->pxms_ptofs = ofs;
473 * pxmc_dummy_con - Dummy controller for synchronous BLDC/PMSM/steper drive
474 * @mcs: Motion controller state information
477 pxmc_dummy_con(pxmc_state_t *mcs)
482 pxmc_call_t *pxmc_get_hh_gi_4axis(pxmc_state_t *mcs)
487 int pxmc_fill_ptscale_for_sin_fixed(pxmc_state_t *mcs)
489 unsigned long ptirc = mcs->pxms_ptirc;
490 unsigned long ptper = mcs->pxms_ptper;
491 unsigned long scale_mult;
492 unsigned long scale_shift;
498 scale_mult = (ptper + ptirc / 2) / ptirc;
500 scale_mult <<= 32 - shift;
502 scale_mult >>= shift - 32;
504 mcs->pxms_ptscale_mult = scale_mult & 0xffff;
505 mcs->pxms_ptscale_shift = scale_mult >> 16;
511 spimc_state_t spimc_state0 = {
512 #ifndef APPL_WITH_ZYNQ_DRV
513 //.spi_dev = "/dev/spidev0.1",
514 .spi_dev = "/dev/spidev1.0",
515 #endif /*APPL_WITH_ZYNQ_DRV*/
518 pxmc_spimc_state_t mcs0 =
526 pxmc_pid_con /*pxmc_dummy_con*/,
528 pxmc_spimc_pwm3ph_out /*pxmc_spimc_pwm_dc_out*/,
532 pxmc_inp_spimc_ap2hw,
533 .pxms_ap = 0, .pxms_as = 0,
534 .pxms_rp = 55 * 256, .pxms_rs = 0,
535 #ifndef PXMC_WITH_FIXED_SUBDIV
537 #endif /*PXMC_WITH_FIXED_SUBDIV*/
538 .pxms_md = 800 << 8, .pxms_ms = 500, .pxms_ma = 10,
541 .pxms_ene = 0, .pxms_erc = 0,
542 .pxms_p = 40, .pxms_i = 10, .pxms_d = 100, .pxms_s1 = 0, .pxms_s2 = 0,
543 .pxms_me = 0x7e00/*0x7fff*/,
545 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m * 0 |
546 PXMS_CFG_HRI_m * 0 | PXMS_CFG_HDIR_m * 0 |
547 PXMS_CFG_I2PT_m * 0 | 0x2,
552 /*.pxms_ptamp = 0x7fff,*/
556 .spimc_state = &spimc_state0,
565 pxmc_state_t *pxmc_main_arr[PXML_MAIN_CNT] = {&mcs0.base};
568 pxmc_state_list_t pxmc_main_list =
576 static inline void pxmc_sfi_input(void)
580 pxmc_for_each_mcs(var, mcs)
582 /* PXMS_ENI_m - check if input (IRC) update is enabled */
583 if (mcs->pxms_flg & PXMS_ENI_m)
585 pxmc_call(mcs, mcs->pxms_do_inp);
590 static inline void pxmc_sfi_controller_and_output(void)
594 pxmc_for_each_mcs(var, mcs)
596 /* PXMS_ENR_m - check if controller is enabled */
597 if (mcs->pxms_flg & PXMS_ENR_m || mcs->pxms_flg & PXMS_ENO_m)
600 /* If output only is enabled, we skip the controller */
601 if (mcs->pxms_flg & PXMS_ENR_m)
604 pxmc_call(mcs, mcs->pxms_do_con);
606 /* PXMS_ERR_m - if axis in error state */
607 if (mcs->pxms_flg & PXMS_ERR_m)
611 /* for bushless motors, it is necessary to call do_out
612 even if the controller is not enabled and PWM should be provided. */
613 pxmc_call(mcs, mcs->pxms_do_out);
618 static inline void pxmc_sfi_generator(void)
622 pxmc_for_each_mcs(var, mcs)
624 /* PXMS_ENG_m - check if requested value (position) generator is enabled */
625 if (mcs->pxms_flg & PXMS_ENG_m)
627 pxmc_call(mcs, mcs->pxms_do_gen);
632 static inline void pxmc_sfi_dbg(void)
636 pxmc_for_each_mcs(var, mcs)
638 if (mcs->pxms_flg & PXMS_DBG_m)
640 pxmc_call(mcs, mcs->pxms_do_deb);
645 static inline void pxmc_spimc_rq_transfer(void)
649 pxmc_spimc_state_t *mcsrc;
651 pxmc_for_each_mcs(var, mcs)
653 mcsrc = pxmc_state2spimc_state(mcs);
654 spimc_transfer(mcsrc->spimc_state);
658 void pxmc_samplig_period(void)
661 pxmc_sfi_controller_and_output();
662 pxmc_spimc_rq_transfer();
663 pxmc_sfi_generator();
669 void *pxmc_base_thread(void *arg)
671 sample_period_t sample_period;
672 sample_period_setup(&sample_period, 1000 * 1000);
675 pxmc_samplig_period();
676 sample_period_wait_next(&sample_period);
680 int pxmc_clear_power_stop(void)
685 int pxmc_process_state_check(unsigned long *pbusy_bits,
686 unsigned long *perror_bits)
690 unsigned long busy_bits = 0;
691 unsigned long error_bits = 0;
694 pxmc_for_each_mcs(chan, mcs) {
696 flg |= mcs->pxms_flg;
697 if (mcs->pxms_flg & PXMS_BSY_m)
698 busy_bits |= 1 << chan;
699 if (mcs->pxms_flg & PXMS_ERR_m)
700 error_bits |= 1 << chan;
703 if (appl_errstop_mode) {
704 if((flg & PXMS_ENG_m) && (flg & PXMS_ERR_m)) {
705 pxmc_for_each_mcs(chan, mcs) {
706 if(mcs&&(mcs->pxms_flg & PXMS_ENG_m)) {
713 if (pbusy_bits != NULL)
714 *pbusy_bits = busy_bits;
715 if (perror_bits != NULL)
716 *perror_bits = error_bits;
721 int pxmc_axis_rdmode(pxmc_state_t *mcs)
723 if (mcs->pxms_do_out == pxmc_spimc_pwm_dc_out)
724 return PXMC_AXIS_MODE_DC;
725 if (mcs->pxms_do_out == pxmc_spimc_pwm3ph_out)
726 return PXMC_AXIS_MODE_BLDC;
731 * pxmc_axis_mode - Sets axis mode.[extern API]
732 * @mcs: Motion controller state information
733 * @mode: 0 .. previous mode, 1 .. stepper motor mode,
734 * 2 .. stepper motor with IRC feedback and PWM ,
735 * 3 .. stepper motor with PWM control
736 * 4 .. DC motor with IRC feedback and PWM
740 pxmc_axis_mode(pxmc_state_t *mcs, int mode)
745 pxmc_axis_release(mcs);
746 pxmc_clear_flag(mcs, PXMS_ENI_b);
747 pxmc_clear_flag(mcs,PXMS_ENO_b);
748 /*TODO Clear possible stall index flags from hardware */
750 pxmc_clear_flag(mcs, PXMS_PHA_b);
751 pxmc_clear_flag(mcs, PXMS_PTI_b);
753 prev_mode = pxmc_axis_rdmode(mcs);
755 if (mode == PXMC_AXIS_MODE_NOCHANGE)
760 mode = PXMC_AXIS_MODE_DC;
763 case PXMC_AXIS_MODE_DC:
764 mcs->pxms_do_out = pxmc_spimc_pwm_dc_out;
766 case PXMC_AXIS_MODE_BLDC:
767 mcs->pxms_do_out = pxmc_spimc_pwm3ph_out;
768 pxmc_fill_ptscale_for_sin_fixed(mcs);
774 /*TODO Clear possible stall index flags from hardware */
776 /* Request new phases alignment for changed parameters */
777 pxmc_clear_flag(mcs, PXMS_PHA_b);
778 pxmc_clear_flag(mcs, PXMS_PTI_b);
779 pxmc_set_flag(mcs, PXMS_ENI_b);
788 if (!pxmc_main_list.pxml_cnt)
791 pxmc_for_each_mcs(var, mcs)
793 pxmc_axis_release(mcs);
796 pxmc_main_list.pxml_cnt = 0;
802 int pxmc_initialize(void)
806 pxmc_main_list.pxml_cnt = 0;
807 pxmc_dbg_hist = NULL;
809 if (spimc_init(mcs0.spimc_state) < 0)
812 pxmc_fill_ptscale_for_sin_fixed(pxmc_main_list.pxml_arr[0]);
815 pxmc_main_list.pxml_cnt = PXML_MAIN_CNT;
817 if (create_rt_task(&pxmc_base_thread_id, 60, pxmc_base_thread, NULL) < 0)