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 #include "pxmc_spimc.h"
40 pthread_t pxmc_base_thread_id;
42 int pxmc_ptofs_from_index(pxmc_state_t *mcs, unsigned long irc,
43 unsigned long index_irc, int diff2err);
45 #define PXML_MAIN_CNT 1
47 #undef PXMC_WITH_PT_ZIC
48 #define PXMC_PT_ZIC_MASK 0x8000
50 #define HAL_ERR_SENSITIVITY 20
51 #define HAL_ERR_MAX_COUNT 5
53 #define PXMC_LXPWR_PWM_CYCLE 2048
55 unsigned pxmc_spimc_pwm_magnitude = PXMC_LXPWR_PWM_CYCLE;
57 unsigned pxmc_spimc_mark_filt[PXML_MAIN_CNT];
58 unsigned pxmc_spimc_lxpwr_chips = 0;
59 int appl_errstop_mode = 0;
62 pxmc_spimc_state_t *pxmc_state2spimc_state(pxmc_state_t *mcs)
64 pxmc_spimc_state_t *mcsrc;
66 mcsrc = UL_CONTAINEROF(mcs, pxmc_spimc_state_t, base);
67 #else /*UL_CONTAINEROF*/
68 mcsrc = (pxmc_spimc_state_t*)((char*)mcs - __builtin_offsetof(pxmc_spimc_state_t, base));
69 #endif /*UL_CONTAINEROF*/
73 const uint8_t onesin10bits[1024]={
74 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,
75 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,
76 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,
77 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,
78 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,
79 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,
80 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
81 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
82 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,
83 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,
84 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,
85 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,
86 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
87 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,
88 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,
89 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,
90 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,
91 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,
92 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
93 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,
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 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
97 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,
98 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,
99 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,
100 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,
101 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,
102 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
103 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,
104 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,
105 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
109 pxmc_inp_spimc_inp(struct pxmc_state *mcs)
111 pxmc_spimc_state_t *mcsrc = pxmc_state2spimc_state(mcs);
112 int chan=mcs->pxms_inp_info;
116 /* read position from hardware */
117 irc = mcsrc->spimc_state->act_pos;
118 irc += mcsrc->spimc_state->pos_offset;
119 pos = irc << PXMC_SUBDIV(mcs);
120 mcs->pxms_as = pos - mcs->pxms_ap;
123 /* Running of the motor commutator */
124 if (mcs->pxms_flg & PXMS_PTI_m)
125 pxmc_irc_16bit_commindx(mcs, irc);
131 pxmc_inp_spimc_ap2hw(struct pxmc_state *mcs)
133 pxmc_spimc_state_t *mcsrc = pxmc_state2spimc_state(mcs);
134 int chan=mcs->pxms_inp_info;
138 irc = mcsrc->spimc_state->act_pos;
139 pos_diff = mcs->pxms_ap - (irc << PXMC_SUBDIV(mcs));
141 irc = pos_diff >> PXMC_SUBDIV(mcs);
143 /* Adjust phase table alignemt to modified IRC readout */
144 mcs->pxms_ptofs += irc - mcsrc->spimc_state->pos_offset;
146 mcsrc->spimc_state->pos_offset = irc;
151 pxmc_spimc_bldc_hal_rd(pxmc_state_t *mcs)
153 pxmc_spimc_state_t *mcsrc = pxmc_state2spimc_state(mcs);
155 int chan = mcs->pxms_out_info;
157 h = mcsrc->spimc_state->hal_sensors;
159 /* return 3 bits corresponding to the HAL senzor input */
164 const unsigned char pxmc_lpc_bdc_hal_pos_table[8] =
176 const unsigned char pxmc_lpc_bdc_hal_pos_table[8] =
189 int pxmc_spimc_pwm_direct_wr(unsigned chan, unsigned pwm, int en)
196 * pxmc_spimc_pwm3ph_wr - Output of the 3-phase PWM to the hardware
197 * @mcs: Motion controller state information
199 /*static*/ inline void
200 pxmc_spimc_pwm3ph_wr(pxmc_state_t *mcs, uint32_t pwm1, uint32_t pwm2, uint32_t pwm3)
202 pxmc_spimc_state_t *mcsrc = pxmc_state2spimc_state(mcs);
203 int chan = mcs->pxms_out_info;
205 mcsrc->spimc_state->pwm[0] = pwm1;
206 mcsrc->spimc_state->pwm[1] = pwm2;
207 mcsrc->spimc_state->pwm[2] = pwm3;
211 pxmc_spimc_process_hal_error(struct pxmc_state *mcs)
213 if (mcs->pxms_halerc >= HAL_ERR_SENSITIVITY * HAL_ERR_MAX_COUNT)
215 pxmc_set_errno(mcs, PXMS_E_HAL);
220 mcs->pxms_halerc += HAL_ERR_SENSITIVITY;
223 pxmc_inp_spimc_ptofs_from_index_poll(struct pxmc_state *mcs, int diff2err)
225 pxmc_spimc_state_t *mcsrc = pxmc_state2spimc_state(mcs);
226 int chan=mcs->pxms_inp_info;
233 irc = mcsrc->spimc_state->act_pos + mcsrc->spimc_state->pos_offset;
234 index_irc = mcsrc->spimc_state->index_pos + mcsrc->spimc_state->pos_offset;
236 return pxmc_ptofs_from_index(mcs, irc, index_irc, diff2err);
240 * pxmc_spimc_pwm3ph_out - Phase output for brush-less 3-phase motor
241 * @mcs: Motion controller state information
244 pxmc_spimc_pwm3ph_out(pxmc_state_t *mcs)
246 pxmc_spimc_state_t *mcsrc = pxmc_state2spimc_state(mcs);
247 typeof(mcs->pxms_ptvang) ptvang;
249 unsigned char hal_pos;
251 int32_t sin_val, cos_val;
252 int32_t pwm_d, pwm_q;
253 int32_t pwm_alp, pwm_bet;
254 uint32_t pwm1, pwm2, pwm3;
258 if (!(mcs->pxms_flg & PXMS_PTI_m) || !(mcs->pxms_flg & PXMS_PHA_m) ||
259 (mcs->pxms_flg & PXMS_PRA_m))
262 short ptirc = mcs->pxms_ptirc;
263 short divisor = mcs->pxms_ptper * 6;
265 hal_pos = pxmc_lpc_bdc_hal_pos_table[pxmc_spimc_bldc_hal_rd(mcs)];
270 pxmc_spimc_process_hal_error(mcs);
274 if (mcs->pxms_halerc)
277 ptindx = (hal_pos * ptirc + divisor / 2) / divisor;
279 if (!(mcs->pxms_flg & PXMS_PTI_m) || (mcs->pxms_flg & PXMS_PRA_m))
281 if (((hal_pos != mcs->pxms_hal) && (mcs->pxms_hal != 0x40)) && 1)
283 short ptindx_prev = (mcs->pxms_hal * ptirc + divisor / 2) / divisor;;
285 if ((ptindx > ptindx_prev + ptirc / 2) ||
286 (ptindx_prev > ptindx + ptirc / 2))
288 ptindx = (ptindx_prev + ptindx - ptirc) / 2;
295 ptindx = (ptindx_prev + ptindx) / 2;
298 mcs->pxms_ptindx = ptindx;
300 mcs->pxms_ptofs = (mcs->pxms_ap >> PXMC_SUBDIV(mcs)) + mcs->pxms_ptshift - ptindx;
302 pxmc_set_flag(mcs, PXMS_PTI_b);
303 pxmc_clear_flag(mcs, PXMS_PRA_b);
307 if (!(mcs->pxms_flg & PXMS_PTI_m))
308 mcs->pxms_ptindx = ptindx;
311 /* if phase table position to mask is know do fine phase table alignment */
312 if (mcs->pxms_cfg & PXMS_CFG_I2PT_m) {
314 res = pxmc_inp_spimc_ptofs_from_index_poll(mcs, 0);
316 pxmc_set_errno(mcs, PXMS_E_I2PT_TOOBIG);
318 pxmc_set_flag(mcs, PXMS_PTI_b);
319 pxmc_set_flag(mcs, PXMS_PHA_b);
323 mcs->pxms_hal = hal_pos;
328 /*wind_current[0]=(ADC->ADDR0 & 0xFFF0)>>4;*/
329 /* FIXME - check winding current against limit */
330 /* pxmc_set_errno(mcs, PXMS_E_WINDCURRENT); */
334 ptvang = mcs->pxms_ptvang;
336 pwm_q = mcs->pxms_ene;
339 pwm_d = mcs->pxms_flg & PXMS_BSY_m? mcs->pxms_me: 0;
343 if (pwm_d || pwm_q) {
345 uint32_t ptscale_mult = mcs->pxms_ptscale_mult |
346 (mcs->pxms_ptscale_shift << 16);
348 indx = mcs->pxms_ptindx;
351 pta = indx + mcs->pxms_ptirc;
357 pta -= PXMC_SIN_FIX_2PI3;
359 pxmc_sincos_fixed_inline(&sin_val, &cos_val, pta, 16);
360 pxmc_dq2alpbet(&pwm_alp, &pwm_bet, pwm_d, pwm_q, sin_val, cos_val);
361 pxmc_alpbet2pwm3ph(&pwm1, &pwm2, &pwm3, pwm_alp, pwm_bet);
363 /*printf("pwm d %4d q %4d alp %4d bet %4d a %4d b %4d c %4d\n",
364 pwm_d, pwm_q, pwm_alp >> 16, pwm_bet >> 16, pwm1, pwm2, pwm3);*/
367 #ifdef PXMC_WITH_PT_ZIC
368 if (labs(mcs->pxms_as) < (10 << PXMC_SUBDIV(mcs)))
371 #endif /*PXMC_WITH_PT_ZIC*/
373 /* Default phase-table amplitude is 0x7fff, ene max is 0x7fff */
374 /* Initialized CTM4 PWM period is 0x200 => divide by value about 2097024 */
376 unsigned long pwm_mag = pxmc_spimc_pwm_magnitude;
378 pwm1 = SPIMC_PWM_SHUTDOWN;
380 pwm1 = (((unsigned long long)pwm1 * pwm_mag) >> 15) | SPIMC_PWM_ENABLE;
382 pwm2 = SPIMC_PWM_SHUTDOWN;
384 pwm2 = (((unsigned long long)pwm2 * pwm_mag) >> 15) | SPIMC_PWM_ENABLE;
386 pwm3 = SPIMC_PWM_SHUTDOWN;
388 pwm3 = (((unsigned long long)pwm3 * pwm_mag) >> 15) | SPIMC_PWM_ENABLE;
390 pxmc_spimc_pwm3ph_wr(mcs, pwm1, pwm2, pwm3);
395 pxmc_spimc_pwm3ph_wr(mcs, 0, 0, 0);
398 /*printf("hal_pos %d pwm %4d %4d %4d\n", hal_pos, pwm1 & 0xffff,
399 pwm2 & 0xffff, pwm3 & 0xffff);*/
405 * pxmc_spimc_pwm_dc_out - DC motor CW and CCW PWM output
406 * @mcs: Motion controller state information
409 pxmc_spimc_pwm_dc_out(pxmc_state_t *mcs)
411 int chan = mcs->pxms_out_info;
412 int ene = mcs->pxms_ene;
418 ene = (ene * (pxmc_spimc_pwm_magnitude + 5)) >> 15;
419 pxmc_spimc_pwm3ph_wr(mcs, SPIMC_PWM_ENABLE, ene | SPIMC_PWM_ENABLE, 0);
423 ene = (ene * (pxmc_spimc_pwm_magnitude + 5)) >> 15;
424 pxmc_spimc_pwm3ph_wr(mcs, ene | SPIMC_PWM_ENABLE, SPIMC_PWM_ENABLE, 0);
430 int pxmc_ptofs_from_index(pxmc_state_t *mcs, unsigned long irc,
431 unsigned long index_irc, int diff2err)
436 ofs = ofsl = index_irc - mcs->pxms_ptmark;
440 diff = (unsigned short)ofs - (unsigned short)mcs->pxms_ptofs;
441 if (diff >= mcs->pxms_ptirc / 2)
442 diff -= mcs->pxms_ptirc;
443 if (diff <= -mcs->pxms_ptirc / 2)
444 diff += mcs->pxms_ptirc;
447 if(diff >= mcs->pxms_ptirc / 6) {
452 diff = (unsigned long)ofsl - irc;
453 ofs = ofsl - (diff / mcs->pxms_ptirc) * mcs->pxms_ptirc;
456 mcs->pxms_ptofs = ofs;
462 * pxmc_dummy_con - Dummy controller for synchronous BLDC/PMSM/steper drive
463 * @mcs: Motion controller state information
466 pxmc_dummy_con(pxmc_state_t *mcs)
471 pxmc_call_t *pxmc_get_hh_gi_4axis(pxmc_state_t *mcs)
476 int pxmc_fill_ptscale_for_sin_fixed(pxmc_state_t *mcs)
478 unsigned long ptirc = mcs->pxms_ptirc;
479 unsigned long ptper = mcs->pxms_ptper;
480 unsigned long scale_mult;
481 unsigned long scale_shift;
487 scale_mult = (ptper + ptirc / 2) / ptirc;
489 scale_mult <<= 32 - shift;
491 scale_mult >>= shift - 32;
493 mcs->pxms_ptscale_mult = scale_mult & 0xffff;
494 mcs->pxms_ptscale_shift = scale_mult >> 16;
499 spimc_state_t spimc_state0 = {
500 .spi_dev = "/dev/spidev0.1",
503 pxmc_spimc_state_t mcs0 =
511 pxmc_pid_con /*pxmc_dummy_con*/,
513 pxmc_spimc_pwm3ph_out /*pxmc_spimc_pwm_dc_out*/,
517 pxmc_inp_spimc_ap2hw,
518 .pxms_ap = 0, .pxms_as = 0,
519 .pxms_rp = 55 * 256, .pxms_rs = 0,
520 #ifndef PXMC_WITH_FIXED_SUBDIV
522 #endif /*PXMC_WITH_FIXED_SUBDIV*/
523 .pxms_md = 800 << 8, .pxms_ms = 500, .pxms_ma = 10,
526 .pxms_ene = 0, .pxms_erc = 0,
527 .pxms_p = 40, .pxms_i = 10, .pxms_d = 100, .pxms_s1 = 0, .pxms_s2 = 0,
528 .pxms_me = 0x7e00/*0x7fff*/,
530 PXMS_CFG_SMTH_m | PXMS_CFG_MD2E_m | PXMS_CFG_HLS_m | PXMS_CFG_HPS_m * 0 |
531 PXMS_CFG_HRI_m * 0 | PXMS_CFG_HDIR_m * 0 |
532 PXMS_CFG_I2PT_m * 0 | 0x2,
537 /*.pxms_ptamp = 0x7fff,*/
541 .spimc_state = &spimc_state0,
550 pxmc_state_t *pxmc_main_arr[PXML_MAIN_CNT] = {&mcs0.base};
553 pxmc_state_list_t pxmc_main_list =
561 static inline void pxmc_sfi_input(void)
565 pxmc_for_each_mcs(var, mcs)
567 /* PXMS_ENI_m - check if input (IRC) update is enabled */
568 if (mcs->pxms_flg & PXMS_ENI_m)
570 pxmc_call(mcs, mcs->pxms_do_inp);
575 static inline void pxmc_sfi_controller_and_output(void)
579 pxmc_for_each_mcs(var, mcs)
581 /* PXMS_ENR_m - check if controller is enabled */
582 if (mcs->pxms_flg & PXMS_ENR_m || mcs->pxms_flg & PXMS_ENO_m)
585 /* If output only is enabled, we skip the controller */
586 if (mcs->pxms_flg & PXMS_ENR_m)
589 pxmc_call(mcs, mcs->pxms_do_con);
591 /* PXMS_ERR_m - if axis in error state */
592 if (mcs->pxms_flg & PXMS_ERR_m)
596 /* for bushless motors, it is necessary to call do_out
597 even if the controller is not enabled and PWM should be provided. */
598 pxmc_call(mcs, mcs->pxms_do_out);
603 static inline void pxmc_sfi_generator(void)
607 pxmc_for_each_mcs(var, mcs)
609 /* PXMS_ENG_m - check if requested value (position) generator is enabled */
610 if (mcs->pxms_flg & PXMS_ENG_m)
612 pxmc_call(mcs, mcs->pxms_do_gen);
617 static inline void pxmc_sfi_dbg(void)
621 pxmc_for_each_mcs(var, mcs)
623 if (mcs->pxms_flg & PXMS_DBG_m)
625 pxmc_call(mcs, mcs->pxms_do_deb);
630 static inline void pxmc_spimc_rq_transfer(void)
634 pxmc_spimc_state_t *mcsrc;
636 pxmc_for_each_mcs(var, mcs)
638 mcsrc = pxmc_state2spimc_state(mcs);
639 spimc_transfer(mcsrc->spimc_state);
643 void pxmc_samplig_period(void)
646 pxmc_sfi_controller_and_output();
647 pxmc_spimc_rq_transfer();
648 pxmc_sfi_generator();
654 void *pxmc_base_thread(void *arg)
656 sample_period_t sample_period;
657 sample_period_setup(&sample_period, 1000 * 1000);
660 pxmc_samplig_period();
661 sample_period_wait_next(&sample_period);
665 int pxmc_clear_power_stop(void)
670 int pxmc_process_state_check(unsigned long *pbusy_bits,
671 unsigned long *perror_bits)
675 unsigned long busy_bits = 0;
676 unsigned long error_bits = 0;
679 pxmc_for_each_mcs(chan, mcs) {
681 flg |= mcs->pxms_flg;
682 if (mcs->pxms_flg & PXMS_BSY_m)
683 busy_bits |= 1 << chan;
684 if (mcs->pxms_flg & PXMS_ERR_m)
685 error_bits |= 1 << chan;
688 if (appl_errstop_mode) {
689 if((flg & PXMS_ENG_m) && (flg & PXMS_ERR_m)) {
690 pxmc_for_each_mcs(chan, mcs) {
691 if(mcs&&(mcs->pxms_flg & PXMS_ENG_m)) {
698 if (pbusy_bits != NULL)
699 *pbusy_bits = busy_bits;
700 if (perror_bits != NULL)
701 *perror_bits = error_bits;
706 int pxmc_axis_rdmode(pxmc_state_t *mcs)
708 if (mcs->pxms_do_out == pxmc_spimc_pwm_dc_out)
709 return PXMC_AXIS_MODE_DC;
710 if (mcs->pxms_do_out == pxmc_spimc_pwm3ph_out)
711 return PXMC_AXIS_MODE_BLDC;
716 * pxmc_axis_mode - Sets axis mode.[extern API]
717 * @mcs: Motion controller state information
718 * @mode: 0 .. previous mode, 1 .. stepper motor mode,
719 * 2 .. stepper motor with IRC feedback and PWM ,
720 * 3 .. stepper motor with PWM control
721 * 4 .. DC motor with IRC feedback and PWM
725 pxmc_axis_mode(pxmc_state_t *mcs, int mode)
730 pxmc_axis_release(mcs);
731 pxmc_clear_flag(mcs, PXMS_ENI_b);
732 pxmc_clear_flag(mcs,PXMS_ENO_b);
733 /*TODO Clear possible stall index flags from hardware */
735 pxmc_clear_flag(mcs, PXMS_PHA_b);
736 pxmc_clear_flag(mcs, PXMS_PTI_b);
738 prev_mode = pxmc_axis_rdmode(mcs);
740 if (mode == PXMC_AXIS_MODE_NOCHANGE)
745 mode = PXMC_AXIS_MODE_DC;
748 case PXMC_AXIS_MODE_DC:
749 mcs->pxms_do_out = pxmc_spimc_pwm_dc_out;
751 case PXMC_AXIS_MODE_BLDC:
752 mcs->pxms_do_out = pxmc_spimc_pwm3ph_out;
753 pxmc_fill_ptscale_for_sin_fixed(mcs);
759 /*TODO Clear possible stall index flags from hardware */
761 /* Request new phases alignment for changed parameters */
762 pxmc_clear_flag(mcs, PXMS_PHA_b);
763 pxmc_clear_flag(mcs, PXMS_PTI_b);
764 pxmc_set_flag(mcs, PXMS_ENI_b);
773 if (!pxmc_main_list.pxml_cnt)
776 pxmc_for_each_mcs(var, mcs)
778 pxmc_axis_release(mcs);
781 pxmc_main_list.pxml_cnt = 0;
787 int pxmc_initialize(void)
791 pxmc_main_list.pxml_cnt = 0;
792 pxmc_dbg_hist = NULL;
794 if (spimc_init(mcs0.spimc_state) < 0)
797 pxmc_fill_ptscale_for_sin_fixed(pxmc_main_list.pxml_arr[0]);
800 pxmc_main_list.pxml_cnt = PXML_MAIN_CNT;
802 if (create_rt_task(&pxmc_base_thread_id, 60, pxmc_base_thread, NULL) < 0)