mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 02:35:23 +03:00
add some more, need a lot of tests
This commit is contained in:
parent
61c2d0ce41
commit
f880421d9e
@ -19,53 +19,50 @@
|
||||
#include "adc.h"
|
||||
#include "buttons.h"
|
||||
#include "commonproto.h"
|
||||
#include "flash.h"
|
||||
#include "hardware.h"
|
||||
#include "hdr.h"
|
||||
#include "proto.h"
|
||||
#include "steppers.h"
|
||||
#include "usb.h"
|
||||
|
||||
|
||||
#define NOPARCHK(par) do{if(PARBASE(par) != CANMESG_NOPAR) return ERR_BADPAR;}while(0)
|
||||
|
||||
#define CHECKN(val, par) do{val = PARBASE(par); \
|
||||
if(val > MOTORSNO-1) return ERR_BADPAR;}while(0)
|
||||
|
||||
extern volatile uint32_t Tms;
|
||||
|
||||
// common functions for CAN and USB (or CAN only functions)
|
||||
|
||||
static errcodes cu_nosuchfn(_U_ uint8_t par, _U_ int32_t *val){ return ERR_BADCMD; }
|
||||
static errcodes cu_nosuchfn(uint8_t _U_ par, int32_t _U_ *val){
|
||||
return ERR_BADCMD;
|
||||
}
|
||||
|
||||
errcodes cu_ping(_U_ uint8_t par, _U_ int32_t *val){
|
||||
errcodes cu_abspos(uint8_t _U_ par, int32_t _U_ *val){
|
||||
uint8_t n; CHECKN(n, par);
|
||||
stopmotor(n);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
static errcodes cu_reset(uint8_t par, _U_ int32_t *val){
|
||||
NOPARCHK(par);
|
||||
NVIC_SystemReset();
|
||||
return ERR_OK;
|
||||
}
|
||||
static errcodes cu_time(uint8_t par, int32_t *val){
|
||||
NOPARCHK(par);
|
||||
*val = Tms;
|
||||
errcodes cu_accel(uint8_t _U_ par, int32_t _U_ *val){
|
||||
uint8_t n; CHECKN(n, par);
|
||||
if(ISSETTER(par)){
|
||||
if(*val/the_conf.microsteps[n] > ACCELMAXSTEPS || *val < 1) return ERR_BADVAL;
|
||||
the_conf.accel[n] = *val;
|
||||
}
|
||||
*val = the_conf.accel[n];
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
errcodes cu_mcut(uint8_t par, int32_t *val){
|
||||
NOPARCHK(par);
|
||||
float f = getMCUtemp();
|
||||
*val = (uint32_t)(f*10.f);
|
||||
return ERR_OK;
|
||||
}
|
||||
errcodes cu_mcuvdd(uint8_t par, int32_t *val){
|
||||
NOPARCHK(par);
|
||||
float f = getVdd();
|
||||
*val = (uint32_t)(f*10.f);
|
||||
return ERR_OK;
|
||||
}
|
||||
errcodes cu_adc(uint8_t par, int32_t *val){
|
||||
uint8_t n = PARBASE(par);
|
||||
if(n > NUMBER_OF_ADC_CHANNELS-1) return ERR_BADPAR;
|
||||
*val = getADCval(n);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
// NON-STANDARD COMMAND!!!!!!!
|
||||
// errcode == keystate, value = last time!!!!
|
||||
errcodes cu_button(uint8_t par, int32_t *val){
|
||||
@ -77,44 +74,259 @@ errcodes cu_button(uint8_t par, int32_t *val){
|
||||
return (uint8_t) keystate(n, (uint32_t*)val);
|
||||
}
|
||||
|
||||
// par - motor number, val - 0/1 for ESW0/1
|
||||
errcodes cu_esw(uint8_t par, int32_t *val){
|
||||
uint8_t n = PARBASE(par), l = *val;
|
||||
if(n >= MOTORSNO || l > 1){
|
||||
*val = CANMESG_NOPAR; // the only chance to understand error
|
||||
return ERR_BADPAR;
|
||||
}
|
||||
*val = ESW_state(n, l);
|
||||
errcodes cu_diagn(uint8_t _U_ par, int32_t _U_ *val){
|
||||
return ERR_BADCMD;
|
||||
}
|
||||
|
||||
errcodes cu_emstop(uint8_t _U_ par, int32_t _U_ *val){
|
||||
uint8_t n; CHECKN(n, par);
|
||||
emstopmotor(n);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
errcodes cu_abspos(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_accel(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_diagn(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_emstop(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_eraseflash(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_eswreact(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_goto(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_gotoz(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_gpio(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_gpioconf(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_maxspeed(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_maxsteps(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_microsteps(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_minspeed(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_motflags(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_motmul(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_motreinit(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_relpos(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_relslow(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_saveconf(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_screen(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_speedlimit(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_state(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_stop(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_tmcbus(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_udata(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_usartstatus(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||
errcodes cu_eraseflash(uint8_t _U_ par, int32_t _U_ *val){
|
||||
NOPARCHK(par);
|
||||
if(erase_storage()) return ERR_CANTRUN;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
// par - motor number
|
||||
errcodes cu_esw(uint8_t par, int32_t *val){
|
||||
uint8_t n; CHECKN(n, par);
|
||||
*val = ESW_state(n);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
errcodes cu_eswreact(uint8_t _U_ par, int32_t _U_ *val){
|
||||
uint8_t n; CHECKN(n, par);
|
||||
if(ISSETTER(par)){
|
||||
if(*val < 0 || *val > ESW_AMOUNT-1) return ERR_BADVAL;
|
||||
the_conf.ESW_reaction[n] = *val;
|
||||
}
|
||||
*val = geteswreact(n);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
errcodes cu_goto(uint8_t _U_ par, int32_t _U_ *val){
|
||||
uint8_t n; CHECKN(n, par);
|
||||
errcodes ret = ERR_OK;
|
||||
if(ISSETTER(par)){
|
||||
ret = setmotpos(n, *val);
|
||||
}
|
||||
getpos(n, val);
|
||||
return ret;
|
||||
}
|
||||
|
||||
errcodes cu_gotoz(uint8_t _U_ par, int32_t _U_ *val){
|
||||
uint8_t n; CHECKN(n, par);
|
||||
return motor_goto0(n);
|
||||
}
|
||||
|
||||
TRUE_INLINE void setextpar(uint8_t val, uint8_t i){
|
||||
switch(val){
|
||||
case 0:
|
||||
EXT_CLEAR(i);
|
||||
break;
|
||||
case 1:
|
||||
EXT_SET(i);
|
||||
break;
|
||||
default:
|
||||
EXT_TOGGLE(i);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: do it right
|
||||
errcodes cu_gpio(uint8_t _U_ par, int32_t _U_ *val){
|
||||
#if EXTNO > 4
|
||||
#error "change the code!!!"
|
||||
#endif
|
||||
uint8_t n = PARBASE(par);
|
||||
#ifdef EBUG
|
||||
USND("par="); printu(par);
|
||||
USND(", n="); USB_putbyte('0'+n); newline();
|
||||
#endif
|
||||
if(n == CANMESG_NOPAR){ // all
|
||||
#ifdef EBUG
|
||||
USND("ALL\n");
|
||||
#endif
|
||||
uint8_t *arr = (uint8_t*)val;
|
||||
if(ISSETTER(par)){
|
||||
for(int i = 0; i < EXTNO; ++i)
|
||||
setextpar(arr[i], i);
|
||||
}
|
||||
for(int i = 0; i < EXTNO; ++i){
|
||||
arr[i] = EXT_CHK(i);
|
||||
}
|
||||
return ERR_OK;
|
||||
}else if(n > EXTNO-1) return ERR_BADPAR;
|
||||
if(ISSETTER(par))
|
||||
setextpar((uint8_t)*val, n);
|
||||
*val = (int32_t) EXT_CHK(n);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
// TODO: configure PU/PD, IN/OUT
|
||||
errcodes cu_gpioconf(uint8_t _U_ par, int32_t _U_ *val){
|
||||
return ERR_BADCMD;
|
||||
}
|
||||
|
||||
// calculate ARR value for given speed, return nearest possible speed
|
||||
static uint16_t getSPD(uint8_t n, int32_t speed){
|
||||
uint32_t ARR = PCLK/(MOTORTIM_PSC+1) / the_conf.microsteps[n] / speed - 1;
|
||||
if(ARR < MOTORTIM_ARRMIN) ARR = MOTORTIM_ARRMIN;
|
||||
else if(ARR > 0xffff) ARR = 0xffff;
|
||||
speed = PCLK/(MOTORTIM_PSC+1) / the_conf.microsteps[n] / (ARR + 1);
|
||||
if(speed > 0xffff) speed = 0xffff;
|
||||
return (uint16_t)speed;
|
||||
}
|
||||
|
||||
errcodes cu_maxspeed(uint8_t _U_ par, int32_t _U_ *val){
|
||||
uint8_t n; CHECKN(n, par);
|
||||
if(ISSETTER(par)){
|
||||
if(*val <= the_conf.minspd[n]) return ERR_BADVAL;
|
||||
the_conf.maxspd[n] = getSPD(n, *val);
|
||||
}
|
||||
*val = the_conf.maxspd[n];
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
errcodes cu_maxsteps(uint8_t _U_ par, int32_t _U_ *val){
|
||||
uint8_t n; CHECKN(n, par);
|
||||
if(ISSETTER(par)){
|
||||
if(*val < 1) return ERR_BADVAL;
|
||||
the_conf.maxsteps[n] = *val;
|
||||
}
|
||||
*val = the_conf.maxsteps[n];
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
errcodes cu_mcut(uint8_t par, int32_t *val){
|
||||
NOPARCHK(par);
|
||||
float f = getMCUtemp();
|
||||
*val = (uint32_t)(f*10.f);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
errcodes cu_mcuvdd(uint8_t par, int32_t *val){
|
||||
NOPARCHK(par);
|
||||
float f = getVdd();
|
||||
*val = (uint32_t)(f*10.f);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
errcodes cu_microsteps(uint8_t _U_ par, int32_t _U_ *val){
|
||||
uint8_t n; CHECKN(n, par);
|
||||
if(ISSETTER(par)){
|
||||
#if MICROSTEPSMAX > 512
|
||||
#error "Change the code anywhere!"
|
||||
#endif
|
||||
uint16_t m = (uint16_t)*val;
|
||||
if(m < 1 || m > MICROSTEPSMAX) return ERR_BADVAL;
|
||||
// find most significant bit
|
||||
if(m != 1<<MSB(m)) return ERR_BADVAL;
|
||||
if(the_conf.maxspd[n] * m > PCLK/(MOTORTIM_PSC+1)/(MOTORTIM_ARRMIN+1)) return ERR_BADVAL;
|
||||
the_conf.microsteps[n] = m;
|
||||
}
|
||||
*val = the_conf.microsteps[n];
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
errcodes cu_minspeed(uint8_t _U_ par, int32_t _U_ *val){
|
||||
uint8_t n; CHECKN(n, par);
|
||||
if(ISSETTER(par)){
|
||||
if(*val >= the_conf.maxspd[n]) return ERR_BADVAL;
|
||||
the_conf.minspd[n] = getSPD(n, *val);
|
||||
}
|
||||
*val = the_conf.minspd[n];
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
errcodes cu_motflags(uint8_t _U_ par, int32_t _U_ *val){
|
||||
uint8_t n; CHECKN(n, par);
|
||||
if(ISSETTER(par)){
|
||||
the_conf.motflags[n] = *((motflags_t*)val);
|
||||
}
|
||||
*(motflags_t*)val = the_conf.motflags[n];
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
errcodes cu_motmul(uint8_t _U_ par, int32_t _U_ *val){
|
||||
return ERR_BADCMD;
|
||||
}
|
||||
|
||||
errcodes cu_motreinit(uint8_t _U_ par, int32_t _U_ *val){
|
||||
NOPARCHK(par);
|
||||
init_steppers();
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
errcodes cu_ping(uint8_t _U_ par, int32_t _U_ *val){
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
errcodes cu_relpos(uint8_t _U_ par, int32_t _U_ *val){
|
||||
uint8_t n; CHECKN(n, par);
|
||||
if(ISSETTER(par)) return motor_relmove(n, *val);
|
||||
return getremainsteps(n, val);
|
||||
}
|
||||
|
||||
errcodes cu_relslow(uint8_t _U_ par, int32_t _U_ *val){
|
||||
uint8_t n; CHECKN(n, par);
|
||||
if(ISSETTER(par)) return motor_relslow(n, *val);
|
||||
return getremainsteps(n, val);
|
||||
}
|
||||
|
||||
static errcodes cu_reset(uint8_t par, int32_t _U_ *val){
|
||||
NOPARCHK(par);
|
||||
NVIC_SystemReset();
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
errcodes cu_saveconf(uint8_t _U_ par, int32_t _U_ *val){
|
||||
NOPARCHK(par);
|
||||
if(store_userconf()) return ERR_CANTRUN;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
errcodes cu_screen(uint8_t _U_ par, int32_t _U_ *val){
|
||||
return ERR_BADCMD;
|
||||
}
|
||||
|
||||
errcodes cu_speedlimit(uint8_t _U_ par, int32_t _U_ *val){
|
||||
uint8_t n; CHECKN(n, par);
|
||||
*val = getSPD(n, 0xffff);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
errcodes cu_state(uint8_t _U_ par, int32_t _U_ *val){
|
||||
uint8_t n; CHECKN(n, par);
|
||||
*val = getmotstate(n);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
errcodes cu_stop(uint8_t _U_ par, int32_t _U_ *val){
|
||||
uint8_t n; CHECKN(n, par);
|
||||
stopmotor(n);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
static errcodes cu_time(uint8_t par, int32_t *val){
|
||||
NOPARCHK(par);
|
||||
*val = Tms;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
errcodes cu_tmcbus(uint8_t _U_ par, int32_t _U_ *val){
|
||||
return ERR_BADCMD;
|
||||
}
|
||||
|
||||
errcodes cu_udata(uint8_t _U_ par, int32_t _U_ *val){
|
||||
return ERR_BADCMD;
|
||||
}
|
||||
|
||||
errcodes cu_usartstatus(uint8_t _U_ par, int32_t _U_ *val){
|
||||
return ERR_BADCMD;
|
||||
}
|
||||
|
||||
|
||||
const fpointer cancmdlist[CCMD_AMOUNT] = {
|
||||
|
||||
@ -94,38 +94,38 @@ extern const fpointer cancmdlist[CCMD_AMOUNT];
|
||||
extern const char* cancmds[CCMD_AMOUNT];
|
||||
|
||||
// all common functions
|
||||
errcodes cu_ping(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_ping(uint8_t par, int32_t *val);
|
||||
// not realized yet
|
||||
errcodes cu_abspos(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_accel(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_adc(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_button(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_canid(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_diagn(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_emstop(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_eraseflash(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_esw(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_eswreact(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_goto(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_gotoz(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_gpio(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_gpioconf(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_maxspeed(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_maxsteps(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_mcut(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_mcuvdd(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_microsteps(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_minspeed(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_motflags(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_motmul(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_motreinit(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_relpos(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_relslow(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_saveconf(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_screen(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_speedlimit(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_state(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_stop(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_tmcbus(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_udata(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_usartstatus(_U_ uint8_t par, _U_ int32_t *val);
|
||||
errcodes cu_abspos(uint8_t par, int32_t *val);
|
||||
errcodes cu_accel(uint8_t par, int32_t *val);
|
||||
errcodes cu_adc(uint8_t par, int32_t *val);
|
||||
errcodes cu_button(uint8_t par, int32_t *val);
|
||||
errcodes cu_canid(uint8_t par, int32_t *val);
|
||||
errcodes cu_diagn(uint8_t par, int32_t *val);
|
||||
errcodes cu_emstop(uint8_t par, int32_t *val);
|
||||
errcodes cu_eraseflash(uint8_t par, int32_t *val);
|
||||
errcodes cu_esw(uint8_t par, int32_t *val);
|
||||
errcodes cu_eswreact(uint8_t par, int32_t *val);
|
||||
errcodes cu_goto(uint8_t par, int32_t *val);
|
||||
errcodes cu_gotoz(uint8_t par, int32_t *val);
|
||||
errcodes cu_gpio(uint8_t par, int32_t *val);
|
||||
errcodes cu_gpioconf(uint8_t par, int32_t *val);
|
||||
errcodes cu_maxspeed(uint8_t par, int32_t *val);
|
||||
errcodes cu_maxsteps(uint8_t par, int32_t *val);
|
||||
errcodes cu_mcut(uint8_t par, int32_t *val);
|
||||
errcodes cu_mcuvdd(uint8_t par, int32_t *val);
|
||||
errcodes cu_microsteps(uint8_t par, int32_t *val);
|
||||
errcodes cu_minspeed(uint8_t par, int32_t *val);
|
||||
errcodes cu_motflags(uint8_t par, int32_t *val);
|
||||
errcodes cu_motmul(uint8_t par, int32_t *val);
|
||||
errcodes cu_motreinit(uint8_t par, int32_t *val);
|
||||
errcodes cu_relpos(uint8_t par, int32_t *val);
|
||||
errcodes cu_relslow(uint8_t par, int32_t *val);
|
||||
errcodes cu_saveconf(uint8_t par, int32_t *val);
|
||||
errcodes cu_screen(uint8_t par, int32_t *val);
|
||||
errcodes cu_speedlimit(uint8_t par, int32_t *val);
|
||||
errcodes cu_state(uint8_t par, int32_t *val);
|
||||
errcodes cu_stop(uint8_t par, int32_t *val);
|
||||
errcodes cu_tmcbus(uint8_t par, int32_t *val);
|
||||
errcodes cu_udata(uint8_t par, int32_t *val);
|
||||
errcodes cu_usartstatus(uint8_t par, int32_t *val);
|
||||
|
||||
@ -32,22 +32,19 @@ static const uint32_t FLASH_blocksize = (uint32_t)&_BLOCKSIZE;
|
||||
// max amount of Config records stored (will be recalculate in flashstorage_init()
|
||||
static uint32_t maxCnum = 1024 / sizeof(user_conf); // can't use blocksize here
|
||||
|
||||
#define DEFMF {.haveencoder = 1, .donthold = 1, .eswinv = 1, .keeppos = 1}
|
||||
#define DEFMF {.donthold = 1}
|
||||
|
||||
#define USERCONF_INITIALIZER { \
|
||||
.userconf_sz = sizeof(user_conf) \
|
||||
,.CANspeed = 100 \
|
||||
,.CANID = 0xaa \
|
||||
,.microsteps = {32, 32, 32} \
|
||||
,.accel = {500, 500, 500} \
|
||||
,.maxspd = {2000, 2000, 2000} \
|
||||
,.minspd = {20, 20, 20} \
|
||||
,.maxsteps = {500000, 500000, 500000} \
|
||||
,.encrev = {4000,4000,4000} \
|
||||
,.encperstepmin = {17,17,17} \
|
||||
,.encperstepmax = {23,23,23} \
|
||||
,.motflags = {DEFMF,DEFMF,DEFMF} \
|
||||
,.ESW_reaction = {ESW_IGNORE, ESW_IGNORE, ESW_IGNORE} \
|
||||
,.microsteps = {32,32,32,32,32,32,32,32}\
|
||||
,.accel = {500,500,500,500,500,500,500,500} \
|
||||
,.maxspd = {2000,2000,2000,2000,2000,2000,2000,2000} \
|
||||
,.minspd = {20,20,20,20,20,20,20,20} \
|
||||
,.maxsteps = {500000,500000,500000,500000,500000,500000,500000,500000}\
|
||||
,.motflags = {DEFMF,DEFMF,DEFMF,DEFMF,DEFMF,DEFMF,DEFMF,DEFMF} \
|
||||
,.ESW_reaction = {ESW_IGNORE,ESW_IGNORE,ESW_IGNORE,ESW_IGNORE,ESW_IGNORE,ESW_IGNORE,ESW_IGNORE,ESW_IGNORE} \
|
||||
}
|
||||
static int erase_flash(const void*, const void*);
|
||||
static int write2flash(const void*, const void*, uint32_t);
|
||||
@ -121,7 +118,7 @@ static int write2flash(const void *start, const void *wrdata, uint32_t stor_size
|
||||
FLASH->KEYR = FLASH_KEY1;
|
||||
FLASH->KEYR = FLASH_KEY2;
|
||||
}
|
||||
while (FLASH->SR & FLASH_SR_BSY);
|
||||
while(FLASH->SR & FLASH_SR_BSY);
|
||||
if(FLASH->SR & FLASH_SR_WRPERR){
|
||||
return 1; // write protection
|
||||
}
|
||||
@ -130,14 +127,14 @@ static int write2flash(const void *start, const void *wrdata, uint32_t stor_size
|
||||
const uint16_t *data = (const uint16_t*) wrdata;
|
||||
volatile uint16_t *address = (volatile uint16_t*) start;
|
||||
uint32_t i, count = (stor_size + 1) / 2;
|
||||
for (i = 0; i < count; ++i){
|
||||
for(i = 0; i < count; ++i){
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
*(volatile uint16_t*)(address + i) = data[i];
|
||||
while (FLASH->SR & FLASH_SR_BSY);
|
||||
if(FLASH->SR & FLASH_SR_PGERR){
|
||||
if(FLASH->SR & FLASH_SR_PGERR){
|
||||
ret = 1; // program error - meet not 0xffff
|
||||
break;
|
||||
}else while (!(FLASH->SR & FLASH_SR_EOP));
|
||||
}
|
||||
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR;
|
||||
}
|
||||
FLASH->CR |= FLASH_CR_LOCK; // lock it back
|
||||
@ -162,41 +159,28 @@ static int erase_flash(const void *start, const void *end){
|
||||
}else{ // erase a part
|
||||
flsz = (uint32_t)end - (uint32_t)start;
|
||||
}
|
||||
if((FLASH->CR & FLASH_CR_LOCK) != 0){
|
||||
FLASH->KEYR = FLASH_KEY1;
|
||||
FLASH->KEYR = FLASH_KEY2;
|
||||
}
|
||||
nblocks = flsz / FLASH_blocksize;
|
||||
if(nblocks == 0 || nblocks >= FLASH_SIZE) return 1;
|
||||
for(uint32_t i = 0; i < nblocks; ++i){
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
/* (1) Wait till no operation is on going */
|
||||
/* (2) Clear error & EOP bits */
|
||||
/* (3) Check that the Flash is unlocked */
|
||||
/* (4) Perform unlock sequence */
|
||||
while ((FLASH->SR & FLASH_SR_BSY) != 0){} /* (1) */
|
||||
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR; /* (2) */
|
||||
/* if (FLASH->SR & FLASH_SR_EOP){
|
||||
FLASH->SR |= FLASH_SR_EOP;
|
||||
}*/
|
||||
if ((FLASH->CR & FLASH_CR_LOCK) != 0){ /* (3) */
|
||||
FLASH->KEYR = FLASH_KEY1; /* (4) */
|
||||
FLASH->KEYR = FLASH_KEY2;
|
||||
}
|
||||
/* (1) Set the PER bit in the FLASH_CR register to enable page erasing */
|
||||
/* (2) Program the FLASH_AR register to select a page to erase */
|
||||
/* (3) Set the STRT bit in the FLASH_CR register to start the erasing */
|
||||
/* (4) Wait until the EOP flag in the FLASH_SR register set */
|
||||
/* (5) Clear EOP flag by software by writing EOP at 1 */
|
||||
/* (6) Reset the PER Bit to disable the page erase */
|
||||
FLASH->CR |= FLASH_CR_PER; /* (1) */
|
||||
FLASH->AR = (uint32_t)Flash_Data + i*FLASH_blocksize; /* (2) */
|
||||
FLASH->CR |= FLASH_CR_STRT; /* (3) */
|
||||
while(!(FLASH->SR & FLASH_SR_EOP));
|
||||
FLASH->SR |= FLASH_SR_EOP; /* (5)*/
|
||||
while(FLASH->SR & FLASH_SR_BSY);
|
||||
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR;
|
||||
FLASH->CR |= FLASH_CR_PER;
|
||||
FLASH->AR = (uint32_t)Flash_Data + i*FLASH_blocksize;
|
||||
FLASH->CR |= FLASH_CR_STRT;
|
||||
while(FLASH->SR & FLASH_SR_BSY);
|
||||
FLASH->SR = FLASH_SR_EOP;
|
||||
if(FLASH->SR & FLASH_SR_WRPERR){ /* Check Write protection error */
|
||||
ret = 1;
|
||||
FLASH->SR |= FLASH_SR_WRPERR; /* Clear the flag by software by writing it at 1*/
|
||||
break;
|
||||
}
|
||||
FLASH->CR &= ~FLASH_CR_PER; /* (6) */
|
||||
}
|
||||
FLASH->CR &= ~FLASH_CR_PER;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -204,7 +188,7 @@ int erase_storage(){
|
||||
return erase_flash(Flash_Data, NULL);
|
||||
}
|
||||
|
||||
int fn_dumpconf(_U_ uint32_t hash, _U_ char *args){ // "dumpconf" (3271513185)
|
||||
int fn_dumpconf(uint32_t _U_ hash, char _U_ *args){ // "dumpconf" (3271513185)
|
||||
#ifdef EBUG
|
||||
USB_sendstr("flashsize="); printu(FLASH_SIZE); USB_putbyte('*');
|
||||
printu(FLASH_blocksize); USB_putbyte('='); printu(FLASH_SIZE*FLASH_blocksize);
|
||||
@ -229,12 +213,6 @@ int fn_dumpconf(_U_ uint32_t hash, _U_ char *args){ // "dumpconf" (3271513185)
|
||||
printu(the_conf.minspd[i]);
|
||||
PROPNAME("maxsteps");
|
||||
printu(the_conf.maxsteps[i]);
|
||||
PROPNAME("encperrev");
|
||||
printu(the_conf.encrev[i]);
|
||||
PROPNAME("encperstepmin");
|
||||
printu(the_conf.encperstepmin[i]);
|
||||
PROPNAME("encperstepmax");
|
||||
printu(the_conf.encperstepmax[i]);
|
||||
PROPNAME("motflags");
|
||||
printuhex(*((uint8_t*)&the_conf.motflags[i]));
|
||||
PROPNAME("eswreaction");
|
||||
|
||||
@ -38,14 +38,15 @@
|
||||
|
||||
#define FLASH_SIZE *((uint16_t*)FLASH_SIZE_REG)
|
||||
|
||||
#define MOTFLAGS_AMOUNT 6
|
||||
// motor flags
|
||||
typedef struct{
|
||||
uint8_t reverse : 1; // bit0 - reversing motor rotation
|
||||
uint8_t encreverse : 1; // bit1 - reversing encoder rotation TODO: configure encoder's timer to downcounting
|
||||
uint8_t haveencoder : 1; // bit2 - have encoder
|
||||
uint8_t encreverse : 1; // bit1 - reversing encoder rotation - NOT USED HERE!!!
|
||||
uint8_t haveencoder : 1; // bit2 - have encoder - NOT USED HERE!!!
|
||||
uint8_t donthold : 1; // bit3 - clear power @ stop (don't hold motor when stopped)
|
||||
uint8_t eswinv : 1; // bit4 - inverse end-switches
|
||||
uint8_t keeppos : 1; // bit5 - keep current position (as servo motor)
|
||||
uint8_t keeppos : 1; // bit5 - keep current position (as servo motor) - NOT USED HERE!!!
|
||||
} motflags_t;
|
||||
|
||||
/*
|
||||
@ -60,11 +61,9 @@ typedef struct __attribute__((packed, aligned(4))){
|
||||
uint16_t maxspd[MOTORSNO]; // max motor speed (steps per second)
|
||||
uint16_t minspd[MOTORSNO]; // min motor speed (steps per second)
|
||||
uint32_t maxsteps[MOTORSNO]; // maximal amount of steps
|
||||
uint16_t encrev[MOTORSNO]; // encoders' counts per revolution
|
||||
uint16_t encperstepmin[MOTORSNO]; // min amount of encoder ticks per one step
|
||||
uint16_t encperstepmax[MOTORSNO]; // max amount of encoder ticks per one step
|
||||
motflags_t motflags[MOTORSNO]; // motor's flags
|
||||
uint8_t ESW_reaction[MOTORSNO]; // end-switches reaction (esw_react)
|
||||
uint8_t isSPI; // ==1 if there's SPI drivers instead of UART
|
||||
} user_conf;
|
||||
|
||||
extern user_conf the_conf; // global user config (read from FLASH to RAM)
|
||||
|
||||
@ -46,6 +46,14 @@ const uint32_t ESWpins[MOTORSNO][ESWNO] = {
|
||||
{1<<7, 1<<8}, // 7
|
||||
};
|
||||
|
||||
// GPIO pins: PB11, PE15, PE14
|
||||
volatile GPIO_TypeDef *EXTports[EXTNO] = {
|
||||
GPIOB, GPIOE, GPIOE
|
||||
};
|
||||
const uint32_t EXTpins[EXTNO] = {
|
||||
1<<11, 1<<15, 1<<14
|
||||
};
|
||||
|
||||
// motors: DIR/EN
|
||||
// EN: 0:PF10, 1:PE1, 2:PB6, 3:PD2, 4:PC9, 5:PD14, 6:PE13, 7:PB1
|
||||
volatile GPIO_TypeDef *ENports[MOTORSNO] = {
|
||||
@ -64,10 +72,17 @@ const uint8_t mottchannels[MOTORSNO] = {1,1,1,1,1,1,1,3};
|
||||
static IRQn_Type motirqs[MOTORSNO] = {
|
||||
TIM15_IRQn, TIM16_IRQn, TIM17_IRQn, TIM2_IRQn, TIM8_CC_IRQn, TIM4_IRQn, TIM1_CC_IRQn, TIM3_IRQn};
|
||||
|
||||
// state 1 - pressed, 0 - released (pin active is zero)
|
||||
uint8_t ESW_state(uint8_t MOTno, uint8_t ESWno){
|
||||
uint8_t val = ((ESWports[MOTno][ESWno]->IDR & ESWpins[MOTno][ESWno]) ? 0 : 1);
|
||||
if(the_conf.motflags[ESWno].eswinv) val = !val;
|
||||
// return two bits: 0 - ESW0, 1 - ESW1 (if inactive -> 1; if active -> 0)
|
||||
uint8_t ESW_state(uint8_t MOTno){
|
||||
uint8_t val = 0;
|
||||
if(the_conf.isSPI){ // only ESW0 used
|
||||
val = ((ESWports[MOTno][0]->IDR & ESWpins[MOTno][0]) ? 0 : 1);
|
||||
if(the_conf.motflags[MOTno].eswinv) val ^= 1;
|
||||
return val;
|
||||
}else for(int i = 0; i < 2; ++i){
|
||||
val |= ((ESWports[MOTno][i]->IDR & ESWpins[MOTno][i]) ? 0 : 1) << i;
|
||||
}
|
||||
if(the_conf.motflags[MOTno].eswinv) val ^= 3;
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
@ -20,6 +20,11 @@
|
||||
|
||||
#include <stm32f3.h>
|
||||
|
||||
// PCLK frequency
|
||||
#ifndef PCLK
|
||||
#define PCLK (48000000)
|
||||
#endif
|
||||
|
||||
// motors' timer PSC = PCLK/Tfreq - 1, Tfreq=16MHz
|
||||
#define MOTORTIM_PSC (2)
|
||||
// minimal ARR value - 99 for 5000 steps per second @ 32 microsteps/step
|
||||
@ -42,8 +47,22 @@ extern const uint32_t BTNpins[BTNSNO];
|
||||
// state 1 - pressed, 0 - released (pin active is zero)
|
||||
#define BTN_state(x) ((BTNports[x]->IDR & BTNpins[x]) ? 0 : 1)
|
||||
|
||||
// motors amount
|
||||
// motors:
|
||||
#define MOTORSNO (8)
|
||||
extern volatile GPIO_TypeDef *ENports[MOTORSNO];
|
||||
extern const uint32_t ENpins[MOTORSNO];
|
||||
#define MOTOR_EN(x) do{ pin_clear(ENports[x], ENpins[x]); }while(0)
|
||||
#define MOTOR_DIS(x) do{ pin_set(ENports[x], ENpins[x]); }while(0)
|
||||
extern volatile GPIO_TypeDef *DIRports[MOTORSNO];
|
||||
extern const uint32_t DIRpins[MOTORSNO];
|
||||
#define MOTOR_CW(x) do{ pin_set(DIRports[x], DIRpins[x]); }while(0)
|
||||
#define MOTOR_CCW(x) do{ pin_clear(DIRports[x], DIRpins[x]); }while(0)
|
||||
// interval of velocity checking (10ms)
|
||||
#define MOTCHKINTERVAL (10)
|
||||
// maximal ticks of encoder per step
|
||||
#define MAXENCTICKSPERSTEP (100)
|
||||
// amount of full steps per revolution
|
||||
#define STEPSPERREV (200)
|
||||
|
||||
// Limit switches: 2 for each motor
|
||||
#define ESWNO (2)
|
||||
@ -51,10 +70,20 @@ extern const uint32_t BTNpins[BTNSNO];
|
||||
extern volatile GPIO_TypeDef *ESWports[MOTORSNO][ESWNO];
|
||||
extern const uint32_t ESWpins[MOTORSNO][ESWNO];
|
||||
|
||||
// extpins amount
|
||||
#define EXTNO (3)
|
||||
extern volatile GPIO_TypeDef *EXTports[EXTNO];
|
||||
extern const uint32_t EXTpins[EXTNO];
|
||||
#define EXT_SET(x) do{ pin_set(EXTports[x], EXTpins[x]); }while(0)
|
||||
#define EXT_CLEAR(x) do{ pin_clear(EXTports[x], EXTpins[x]); }while(0)
|
||||
#define EXT_TOGGLE(x) do{ pin_toggle(EXTports[x], EXTpins[x]); }while(0)
|
||||
#define EXT_CHK(x) (pin_read(EXTports[x], EXTpins[x]))
|
||||
|
||||
extern volatile TIM_TypeDef *mottimers[MOTORSNO];
|
||||
|
||||
extern volatile uint32_t Tms;
|
||||
|
||||
uint8_t ESW_state(uint8_t MOTno, uint8_t ESWno);
|
||||
uint8_t ESW_state(uint8_t MOTno);
|
||||
uint8_t MSB(uint16_t val);
|
||||
void hw_setup();
|
||||
|
||||
|
||||
@ -44,8 +44,6 @@ int fn_canspeed(_U_ uint32_t hash, _U_ char *args) WAL; // "canspeed" (54926599
|
||||
|
||||
int fn_canstat(_U_ uint32_t hash, _U_ char *args) WAL; // "canstat" (237384179)
|
||||
|
||||
int fn_delignlist(_U_ uint32_t hash, _U_ char *args) WAL; // "delignlist" (2235834164)
|
||||
|
||||
int fn_diagn(_U_ uint32_t hash, _U_ char *args) WAL; // "diagn" (2334137736)
|
||||
|
||||
int fn_dumpcmd(_U_ uint32_t hash, _U_ char *args) WAL; // "dumpcmd" (1223955823)
|
||||
@ -54,16 +52,10 @@ int fn_dumpconf(_U_ uint32_t hash, _U_ char *args) WAL; // "dumpconf" (32715131
|
||||
|
||||
int fn_dumperr(_U_ uint32_t hash, _U_ char *args) WAL; // "dumperr" (1223989764)
|
||||
|
||||
int fn_dumpmotflags(_U_ uint32_t hash, _U_ char *args) WAL; // "dumpmotflags" (36159640)
|
||||
|
||||
int fn_emstop(_U_ uint32_t hash, _U_ char *args) WAL; // "emstop" (2965919005)
|
||||
|
||||
int fn_encpos(_U_ uint32_t hash, _U_ char *args) WAL; // "encpos" (3208428301)
|
||||
|
||||
int fn_encrev(_U_ uint32_t hash, _U_ char *args) WAL; // "encrev" (3208460296)
|
||||
|
||||
int fn_encstepmax(_U_ uint32_t hash, _U_ char *args) WAL; // "encstepmax" (1022989757)
|
||||
|
||||
int fn_encstepmin(_U_ uint32_t hash, _U_ char *args) WAL; // "encstepmin" (1022990779)
|
||||
|
||||
int fn_eraseflash(_U_ uint32_t hash, _U_ char *args) WAL; // "eraseflash" (3177247267)
|
||||
|
||||
int fn_esw(_U_ uint32_t hash, _U_ char *args) WAL; // "esw" (2963094612)
|
||||
@ -194,9 +186,6 @@ int parsecmd(const char *str){
|
||||
case CMD_CANSTAT:
|
||||
return fn_canstat(h, args);
|
||||
break;
|
||||
case CMD_DELIGNLIST:
|
||||
return fn_delignlist(h, args);
|
||||
break;
|
||||
case CMD_DIAGN:
|
||||
return fn_diagn(h, args);
|
||||
break;
|
||||
@ -209,21 +198,12 @@ int parsecmd(const char *str){
|
||||
case CMD_DUMPERR:
|
||||
return fn_dumperr(h, args);
|
||||
break;
|
||||
case CMD_DUMPMOTFLAGS:
|
||||
return fn_dumpmotflags(h, args);
|
||||
break;
|
||||
case CMD_EMSTOP:
|
||||
return fn_emstop(h, args);
|
||||
break;
|
||||
case CMD_ENCPOS:
|
||||
return fn_encpos(h, args);
|
||||
break;
|
||||
case CMD_ENCREV:
|
||||
return fn_encrev(h, args);
|
||||
break;
|
||||
case CMD_ENCSTEPMAX:
|
||||
return fn_encstepmax(h, args);
|
||||
break;
|
||||
case CMD_ENCSTEPMIN:
|
||||
return fn_encstepmin(h, args);
|
||||
break;
|
||||
case CMD_ERASEFLASH:
|
||||
return fn_eraseflash(h, args);
|
||||
break;
|
||||
|
||||
@ -30,16 +30,12 @@ int parsecmd(const char *cmdwargs);
|
||||
#define CMD_CANSEND (237136225)
|
||||
#define CMD_CANSPEED (549265992)
|
||||
#define CMD_CANSTAT (237384179)
|
||||
#define CMD_DELIGNLIST (2235834164)
|
||||
#define CMD_DIAGN (2334137736)
|
||||
#define CMD_DUMPCMD (1223955823)
|
||||
#define CMD_DUMPCONF (3271513185)
|
||||
#define CMD_DUMPERR (1223989764)
|
||||
#define CMD_DUMPMOTFLAGS (36159640)
|
||||
#define CMD_EMSTOP (2965919005)
|
||||
#define CMD_ENCPOS (3208428301)
|
||||
#define CMD_ENCREV (3208460296)
|
||||
#define CMD_ENCSTEPMAX (1022989757)
|
||||
#define CMD_ENCSTEPMIN (1022990779)
|
||||
#define CMD_ERASEFLASH (3177247267)
|
||||
#define CMD_ESW (2963094612)
|
||||
#define CMD_ESWREACT (1614224995)
|
||||
|
||||
@ -40,7 +40,7 @@ int main(void){
|
||||
StartHSI();
|
||||
SysTick_Config((uint32_t)48000); // 1ms
|
||||
}
|
||||
flashstorage_init();
|
||||
//flashstorage_init();
|
||||
hw_setup(); // GPIO, ADC, timers, watchdog etc.
|
||||
USBPU_OFF(); // make a reconnection
|
||||
USB_setup();
|
||||
|
||||
Binary file not shown.
@ -19,6 +19,7 @@ proto.c
|
||||
proto.h
|
||||
ringbuffer.c
|
||||
ringbuffer.h
|
||||
steppers.c
|
||||
steppers.h
|
||||
strfunc.c
|
||||
strfunc.h
|
||||
|
||||
@ -22,11 +22,12 @@
|
||||
#include "adc.h"
|
||||
#include "buttons.h"
|
||||
#include "can.h"
|
||||
#include "commonproto.h"
|
||||
#include "flash.h"
|
||||
#include "hardware.h"
|
||||
#include "hdr.h"
|
||||
#include "proto.h"
|
||||
#include "commonproto.h"
|
||||
#include "steppers.h"
|
||||
#include "version.inc"
|
||||
|
||||
// software ignore buffer size
|
||||
@ -90,7 +91,7 @@ const char *helpstring =
|
||||
#include "hashgen/helpcmds.in"
|
||||
;
|
||||
|
||||
int fn_canignore(_U_ uint32_t hash, char *args){
|
||||
int fn_canignore(uint32_t _U_ hash, char *args){
|
||||
if(!*args){
|
||||
if(IgnSz == 0){
|
||||
USND("Ignore buffer is empty");
|
||||
@ -131,7 +132,7 @@ int fn_canignore(_U_ uint32_t hash, char *args){
|
||||
return RET_GOOD;
|
||||
}
|
||||
|
||||
int fn_canreinit(_U_ uint32_t hash, _U_ char *args){
|
||||
int fn_canreinit(uint32_t _U_ hash, char _U_ *args){
|
||||
CAN_reinit(0);
|
||||
USND("OK");
|
||||
return RET_GOOD;
|
||||
@ -279,18 +280,18 @@ static void add_filter(const char *str){
|
||||
printu(nfilt); USB_sendstr(" parameters");
|
||||
}
|
||||
|
||||
int fn_canfilter(_U_ uint32_t hash, char *args){
|
||||
int fn_canfilter(uint32_t _U_ hash, char *args){
|
||||
if(*args) add_filter(args);
|
||||
else list_filters();
|
||||
return RET_GOOD;
|
||||
}
|
||||
|
||||
int fn_canflood(_U_ uint32_t hash, char *args){
|
||||
int fn_canflood(uint32_t _U_ hash, char *args){
|
||||
CAN_flood(parseCANmsg(args), 0);
|
||||
return RET_GOOD;
|
||||
}
|
||||
|
||||
int fn_cansend(_U_ uint32_t hash, char *args){
|
||||
int fn_cansend(uint32_t _U_ hash, char *args){
|
||||
if(CAN->MSR & CAN_MSR_INAK){
|
||||
USB_sendstr("CAN bus is off, try to restart it\n");
|
||||
return RET_GOOD;
|
||||
@ -305,7 +306,7 @@ int fn_cansend(_U_ uint32_t hash, char *args){
|
||||
return RET_GOOD;
|
||||
}
|
||||
|
||||
int fn_canfloodt(_U_ uint32_t hash, char *args){
|
||||
int fn_canfloodt(uint32_t _U_ hash, char *args){
|
||||
uint32_t N;
|
||||
const char *n = getnum(args, &N);
|
||||
if(args == n){
|
||||
@ -316,7 +317,7 @@ int fn_canfloodt(_U_ uint32_t hash, char *args){
|
||||
return RET_GOOD;
|
||||
}
|
||||
|
||||
int fn_canstat(_U_ uint32_t hash, _U_ char *args){
|
||||
int fn_canstat(uint32_t _U_ hash, char _U_ *args){
|
||||
USB_sendstr("CAN_MSR=");
|
||||
printuhex(CAN->MSR);
|
||||
USB_sendstr("\nCAN_TSR=");
|
||||
@ -329,18 +330,18 @@ int fn_canstat(_U_ uint32_t hash, _U_ char *args){
|
||||
return RET_GOOD;
|
||||
}
|
||||
|
||||
int fn_canerrcodes(_U_ uint32_t hash, _U_ char *args){
|
||||
int fn_canerrcodes(uint32_t _U_ hash, char _U_ *args){
|
||||
CAN_printerr();
|
||||
return RET_GOOD;
|
||||
}
|
||||
|
||||
int fn_canincrflood(_U_ uint32_t hash, _U_ char *args){
|
||||
int fn_canincrflood(uint32_t _U_ hash, char _U_ *args){
|
||||
CAN_flood(NULL, 1);
|
||||
USB_sendstr("Incremental flooding is ON ('F' to off)\n");
|
||||
return RET_GOOD;
|
||||
}
|
||||
|
||||
int fn_canspeed(_U_ uint32_t hash, _U_ char *args){
|
||||
int fn_canspeed(uint32_t _U_ hash, char _U_ *args){
|
||||
uint32_t N;
|
||||
const char *n = getnum(args, &N);
|
||||
if(args == n){
|
||||
@ -363,20 +364,20 @@ int fn_canspeed(_U_ uint32_t hash, _U_ char *args){
|
||||
return RET_GOOD;
|
||||
}
|
||||
|
||||
int fn_canpause(_U_ uint32_t hash, _U_ char *args){
|
||||
int fn_canpause(uint32_t _U_ hash, char _U_ *args){
|
||||
ShowMsgs = TRUE;
|
||||
USND("Pause CAN messages");
|
||||
return RET_GOOD;
|
||||
}
|
||||
|
||||
int fn_canresume(_U_ uint32_t hash, _U_ char *args){
|
||||
int fn_canresume(uint32_t _U_ hash, char _U_ *args){
|
||||
ShowMsgs = FALSE;
|
||||
USND("RESUME CAN messages");
|
||||
return RET_GOOD;
|
||||
}
|
||||
|
||||
// dump base commands codes (for CAN protocol)
|
||||
int fn_dumpcmd(_U_ uint32_t hash, _U_ char *args){ // "dumpcmd" (1223955823)
|
||||
int fn_dumpcmd(uint32_t _U_ hash, char _U_ *args){ // "dumpcmd" (1223955823)
|
||||
USB_sendstr("CANbus commands list:\n");
|
||||
for(uint16_t i = 1; i < CCMD_AMOUNT; ++i){
|
||||
if(!cancmds[i]) continue;
|
||||
@ -388,20 +389,48 @@ int fn_dumpcmd(_U_ uint32_t hash, _U_ char *args){ // "dumpcmd" (1223955823)
|
||||
return RET_GOOD;
|
||||
}
|
||||
|
||||
int fn_reset(_U_ uint32_t hash, _U_ char *args){ // "reset" (1907803304)
|
||||
int fn_reset(uint32_t _U_ hash, char _U_ *args){ // "reset" (1907803304)
|
||||
USB_sendstr("Soft reset\n");
|
||||
USB_sendall(); // wait until everything will gone
|
||||
NVIC_SystemReset();
|
||||
return RET_GOOD;
|
||||
}
|
||||
|
||||
int fn_time(_U_ uint32_t hash, _U_ char *args){ // "time" (19148340)
|
||||
int fn_time(uint32_t _U_ hash, char _U_ *args){ // "time" (19148340)
|
||||
USB_sendstr("Time (ms): ");
|
||||
printu(Tms);
|
||||
USB_putbyte('\n');
|
||||
return RET_GOOD;
|
||||
}
|
||||
|
||||
|
||||
static const char* motfl[MOTFLAGS_AMOUNT] = {
|
||||
"reverse - invert motor's rotation",
|
||||
"[reserved]",
|
||||
"[reserved]",
|
||||
"donthold - clear motor's power after stop",
|
||||
"eswinv - inverse end-switches (1->0 instead of 0->1)",
|
||||
"[reserved]"
|
||||
};
|
||||
static const char *eswfl[ESW_AMOUNT] = {
|
||||
[ESW_IGNORE] = "ignore end-switches",
|
||||
[ESW_ANYSTOP] = "stop @ esw in any moving direction",
|
||||
[ESW_STOPMINUS] = "stop only when moving in given direction (e.g. to minus @ESW0)"
|
||||
};
|
||||
int fn_dumpmotflags(uint32_t _U_ hash, char _U_ *args){ // "dumpmotflags" (36159640)
|
||||
USB_sendstr("Motor flags:");
|
||||
for(int i = 0; i < MOTFLAGS_AMOUNT; ++i){
|
||||
USB_sendstr("\nbit"); printu(i); USB_sendstr(" - ");
|
||||
USB_sendstr(motfl[i]);
|
||||
}
|
||||
USND("\nEnd-switches reaction:");
|
||||
for(int i = 0; i < ESW_AMOUNT; ++i){
|
||||
printu(i); USB_sendstr(" - ");
|
||||
USB_sendstr(eswfl[i]); newline();
|
||||
}
|
||||
return RET_GOOD;
|
||||
}
|
||||
|
||||
static const char* errtxt[ERR_AMOUNT] = {
|
||||
[ERR_OK] = "all OK",
|
||||
[ERR_BADPAR] = "wrong parameter's value",
|
||||
@ -410,7 +439,7 @@ static const char* errtxt[ERR_AMOUNT] = {
|
||||
[ERR_BADCMD] = "unknown command",
|
||||
[ERR_CANTRUN] = "temporary can't run given command",
|
||||
};
|
||||
int fn_dumperr(_U_ uint32_t hash, _U_ char *args){ // "dumperr" (1223989764)
|
||||
int fn_dumperr(uint32_t _U_ hash, char _U_ *args){ // "dumperr" (1223989764)
|
||||
USND("Error codes:");
|
||||
for(int i = 0; i < ERR_AMOUNT; ++i){
|
||||
printu(i); USB_sendstr(" - ");
|
||||
@ -419,7 +448,7 @@ int fn_dumperr(_U_ uint32_t hash, _U_ char *args){ // "dumperr" (1223989764)
|
||||
return RET_GOOD;
|
||||
}
|
||||
|
||||
int fn_canid(_U_ uint32_t hash, char *args){ // "canid" (2040257924)
|
||||
int fn_canid(uint32_t _U_ hash, char *args){ // "canid" (2040257924)
|
||||
if(args && *args){
|
||||
int good = FALSE;
|
||||
uint32_t N;
|
||||
@ -442,6 +471,8 @@ static int canusb_function(uint32_t hash, char *args){
|
||||
int32_t val = 0;
|
||||
uint8_t par = CANMESG_NOPAR;
|
||||
float f;
|
||||
USB_sendstr("CMD: hash="); printu(hash); USB_sendstr(", args=");
|
||||
USND(args);
|
||||
if(*args){
|
||||
const char *n = getnum(args, &N);
|
||||
if(n != args){ // get parameter
|
||||
@ -452,7 +483,7 @@ static int canusb_function(uint32_t hash, char *args){
|
||||
par = (uint8_t) N;
|
||||
n = strchr(n, '=');
|
||||
if(n){
|
||||
const char *nxt = getnum(n, &N);
|
||||
const char *nxt = getnum(n+1, &N);
|
||||
if(nxt != n){ // give flag issetter
|
||||
val = (int32_t) N;
|
||||
par |= SETTERFLAG;
|
||||
@ -460,6 +491,8 @@ static int canusb_function(uint32_t hash, char *args){
|
||||
}
|
||||
}
|
||||
}
|
||||
USB_sendstr("par="); printuhex(par);
|
||||
USB_sendstr(", val="); printi(val); newline();
|
||||
switch(hash){
|
||||
case CMD_PING:
|
||||
e = cu_ping(par, &val);
|
||||
@ -521,7 +554,89 @@ static int canusb_function(uint32_t hash, char *args){
|
||||
case CMD_ESW:
|
||||
e = cu_esw(par, &val);
|
||||
break;
|
||||
case CMD_ERASEFLASH:
|
||||
e = cu_eraseflash(par, &val);
|
||||
break;
|
||||
case CMD_ACCEL:
|
||||
e = cu_accel(par, &val);
|
||||
break;
|
||||
case CMD_ABSPOS:
|
||||
e = cu_abspos(par, &val);
|
||||
break;
|
||||
case CMD_DIAGN:
|
||||
e = cu_diagn(par, &val);
|
||||
break;
|
||||
case CMD_EMSTOP:
|
||||
e = cu_emstop(par, &val);
|
||||
break;
|
||||
case CMD_ESWREACT:
|
||||
e = cu_eswreact(par, &val);
|
||||
break;
|
||||
case CMD_GOTO:
|
||||
e = cu_goto(par, &val);
|
||||
break;
|
||||
case CMD_GOTOZ:
|
||||
e = cu_gotoz(par, &val);
|
||||
break;
|
||||
case CMD_GPIO:
|
||||
e = cu_gpio(par, &val);
|
||||
break;
|
||||
case CMD_GPIOCONF:
|
||||
e = cu_gpioconf(par, &val);
|
||||
break;
|
||||
case CMD_MAXSPEED:
|
||||
e = cu_maxspeed(par, &val);
|
||||
break;
|
||||
case CMD_MAXSTEPS:
|
||||
e = cu_maxsteps(par, &val);
|
||||
break;
|
||||
case CMD_MICROSTEPS:
|
||||
e = cu_microsteps(par, &val);
|
||||
break;
|
||||
case CMD_MINSPEED:
|
||||
e = cu_minspeed(par, &val);
|
||||
break;
|
||||
case CMD_MOTFLAGS:
|
||||
e = cu_motflags(par, &val);
|
||||
break;
|
||||
case CMD_MOTMUL:
|
||||
e = cu_motmul(par, &val);
|
||||
break;
|
||||
case CMD_MOTREINIT:
|
||||
e = cu_motreinit(par, &val);
|
||||
break;
|
||||
case CMD_RELPOS:
|
||||
e = cu_relpos(par, &val);
|
||||
break;
|
||||
case CMD_RELSLOW:
|
||||
e = cu_relslow(par, &val);
|
||||
break;
|
||||
case CMD_SAVECONF:
|
||||
e = cu_saveconf(par, &val);
|
||||
break;
|
||||
case CMD_SCREEN:
|
||||
e = cu_screen(par, &val);
|
||||
break;
|
||||
case CMD_SPEEDLIMIT:
|
||||
e = cu_speedlimit(par, &val);
|
||||
break;
|
||||
case CMD_STATE:
|
||||
e = cu_state(par, &val);
|
||||
break;
|
||||
case CMD_STOP:
|
||||
e = cu_stop(par, &val);
|
||||
break;
|
||||
case CMD_TMCBUS:
|
||||
e = cu_tmcbus(par, &val);
|
||||
break;
|
||||
case CMD_UDATA:
|
||||
e = cu_udata(par, &val);
|
||||
break;
|
||||
case CMD_USARTSTATUS:
|
||||
e = cu_usartstatus(par, &val);
|
||||
break;
|
||||
default:
|
||||
e = ERR_BADCMD;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -541,40 +656,40 @@ static int canusb_function(uint32_t hash, char *args){
|
||||
#define AL __attribute__ ((alias ("canusb_function")))
|
||||
|
||||
// COMMON with CAN
|
||||
int fn_ping(_U_ uint32_t hash, _U_ char *args) AL; // "ping" (10561715)
|
||||
int fn_ping(uint32_t _U_ hash, char _U_ *args) AL; // "ping" (10561715)
|
||||
// not realized yet
|
||||
int fn_abspos(_U_ uint32_t hash, _U_ char *args) AL; //* "abspos" (3056382221)
|
||||
int fn_accel(_U_ uint32_t hash, _U_ char *args) AL; //* "accel" (1490521981)
|
||||
int fn_adc(_U_ uint32_t hash, _U_ char *args) AL; // "adc" (2963026093)
|
||||
int fn_button(_U_ uint32_t hash, _U_ char *args) AL; // "button" (1093508897)
|
||||
int fn_diagn(_U_ uint32_t hash, _U_ char *args) AL; //* "diagn" (2334137736)
|
||||
int fn_emstop(_U_ uint32_t hash, _U_ char *args) AL; //* "emstop" (2965919005)
|
||||
int fn_eraseflash(_U_ uint32_t hash, _U_ char *args) AL; //* "eraseflash" (3177247267)
|
||||
int fn_esw(_U_ uint32_t hash, _U_ char *args) AL; // "esw" (2963094612)
|
||||
int fn_eswreact(_U_ uint32_t hash, _U_ char *args) AL; //* "eswreact" (1614224995)
|
||||
int fn_goto(_U_ uint32_t hash, _U_ char *args) AL; //* "goto" (4286309438)
|
||||
int fn_gotoz(_U_ uint32_t hash, _U_ char *args) AL; //* "gotoz" (3178103736)
|
||||
int fn_gpio(_U_ uint32_t hash, _U_ char *args) AL; //* "gpio" (4286324660)
|
||||
int fn_gpioconf(_U_ uint32_t hash, _U_ char *args) AL; //* "gpioconf" (1309721562)
|
||||
int fn_maxspeed(_U_ uint32_t hash, _U_ char *args) AL; //* "maxspeed" (1498078812)
|
||||
int fn_maxsteps(_U_ uint32_t hash, _U_ char *args) AL; //* "maxsteps" (1506667002)
|
||||
int fn_mcut(_U_ uint32_t hash, _U_ char *args) AL; // "mcut" (4022718)
|
||||
int fn_mcuvdd(_U_ uint32_t hash, _U_ char *args) AL; // "mcuvdd" (2517587080)
|
||||
int fn_microsteps(_U_ uint32_t hash, _U_ char *args) AL; //* "microsteps" (3974395854)
|
||||
int fn_minspeed(_U_ uint32_t hash, _U_ char *args) AL; //* "minspeed" (3234848090)
|
||||
int fn_motflags(_U_ uint32_t hash, _U_ char *args) AL; //* "motflags" (2153634658)
|
||||
int fn_motmul(_U_ uint32_t hash, _U_ char *args) AL; //* "motmul" (1543400099)
|
||||
int fn_motreinit(_U_ uint32_t hash, _U_ char *args) AL; //* "motreinit" (199682784)
|
||||
int fn_relpos(_U_ uint32_t hash, _U_ char *args) AL; //* "relpos" (1278646042)
|
||||
int fn_relslow(_U_ uint32_t hash, _U_ char *args) AL; //* "relslow" (1742971917)
|
||||
int fn_saveconf(_U_ uint32_t hash, _U_ char *args) AL; //* "saveconf" (141102426)
|
||||
int fn_screen(_U_ uint32_t hash, _U_ char *args) AL; //* "screen" (2100809349)
|
||||
int fn_speedlimit(_U_ uint32_t hash, _U_ char *args) AL; //* "speedlimit" (1654184245)
|
||||
int fn_state(_U_ uint32_t hash, _U_ char *args) AL; //* "state" (2216628902)
|
||||
int fn_stop(_U_ uint32_t hash, _U_ char *args) AL; //* "stop" (17184971)
|
||||
int fn_tmcbus(_U_ uint32_t hash, _U_ char *args) AL; //* "tmcbus" (1906135955)
|
||||
int fn_udata(_U_ uint32_t hash, _U_ char *args) AL; //* "udata" (2736127636)
|
||||
int fn_usartstatus(_U_ uint32_t hash, _U_ char *args) AL; //* "usartstatus" (4007098968)
|
||||
int fn_abspos(uint32_t _U_ hash, char _U_ *args) AL; //* "abspos" (3056382221)
|
||||
int fn_accel(uint32_t _U_ hash, char _U_ *args) AL; //* "accel" (1490521981)
|
||||
int fn_adc(uint32_t _U_ hash, char _U_ *args) AL; // "adc" (2963026093)
|
||||
int fn_button(uint32_t _U_ hash, char _U_ *args) AL; // "button" (1093508897)
|
||||
int fn_diagn(uint32_t _U_ hash, char _U_ *args) AL; //* "diagn" (2334137736)
|
||||
int fn_emstop(uint32_t _U_ hash, char _U_ *args) AL; //* "emstop" (2965919005)
|
||||
int fn_eraseflash(uint32_t _U_ hash, char _U_ *args) AL; //* "eraseflash" (3177247267)
|
||||
int fn_esw(uint32_t _U_ hash, char _U_ *args) AL; // "esw" (2963094612)
|
||||
int fn_eswreact(uint32_t _U_ hash, char _U_ *args) AL; //* "eswreact" (1614224995)
|
||||
int fn_goto(uint32_t _U_ hash, char _U_ *args) AL; //* "goto" (4286309438)
|
||||
int fn_gotoz(uint32_t _U_ hash, char _U_ *args) AL; //* "gotoz" (3178103736)
|
||||
int fn_gpio(uint32_t _U_ hash, char _U_ *args) AL; //* "gpio" (4286324660)
|
||||
int fn_gpioconf(uint32_t _U_ hash, char _U_ *args) AL; //* "gpioconf" (1309721562)
|
||||
int fn_maxspeed(uint32_t _U_ hash, char _U_ *args) AL; //* "maxspeed" (1498078812)
|
||||
int fn_maxsteps(uint32_t _U_ hash, char _U_ *args) AL; //* "maxsteps" (1506667002)
|
||||
int fn_mcut(uint32_t _U_ hash, char _U_ *args) AL; // "mcut" (4022718)
|
||||
int fn_mcuvdd(uint32_t _U_ hash, char _U_ *args) AL; // "mcuvdd" (2517587080)
|
||||
int fn_microsteps(uint32_t _U_ hash, char _U_ *args) AL; //* "microsteps" (3974395854)
|
||||
int fn_minspeed(uint32_t _U_ hash, char _U_ *args) AL; //* "minspeed" (3234848090)
|
||||
int fn_motflags(uint32_t _U_ hash, char _U_ *args) AL; //* "motflags" (2153634658)
|
||||
int fn_motmul(uint32_t _U_ hash, char _U_ *args) AL; //* "motmul" (1543400099)
|
||||
int fn_motreinit(uint32_t _U_ hash, char _U_ *args) AL; //* "motreinit" (199682784)
|
||||
int fn_relpos(uint32_t _U_ hash, char _U_ *args) AL; //* "relpos" (1278646042)
|
||||
int fn_relslow(uint32_t _U_ hash, char _U_ *args) AL; //* "relslow" (1742971917)
|
||||
int fn_saveconf(uint32_t _U_ hash, char _U_ *args) AL; //* "saveconf" (141102426)
|
||||
int fn_screen(uint32_t _U_ hash, char _U_ *args) AL; //* "screen" (2100809349)
|
||||
int fn_speedlimit(uint32_t _U_ hash, char _U_ *args) AL; //* "speedlimit" (1654184245)
|
||||
int fn_state(uint32_t _U_ hash, char _U_ *args) AL; //* "state" (2216628902)
|
||||
int fn_stop(uint32_t _U_ hash, char _U_ *args) AL; //* "stop" (17184971)
|
||||
int fn_tmcbus(uint32_t _U_ hash, char _U_ *args) AL; //* "tmcbus" (1906135955)
|
||||
int fn_udata(uint32_t _U_ hash, char _U_ *args) AL; //* "udata" (2736127636)
|
||||
int fn_usartstatus(uint32_t _U_ hash, char _U_ *args) AL; //* "usartstatus" (4007098968)
|
||||
|
||||
|
||||
/**
|
||||
|
||||
470
F3:F303/Multistepper/steppers.c
Normal file
470
F3:F303/Multistepper/steppers.c
Normal file
@ -0,0 +1,470 @@
|
||||
/*
|
||||
* This file is part of the multistepper project.
|
||||
* Copyright 2023 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "flash.h"
|
||||
#include "hardware.h"
|
||||
#include "proto.h"
|
||||
#include "steppers.h"
|
||||
#include "strfunc.h"
|
||||
#include "usb.h"
|
||||
|
||||
// goto zero stages
|
||||
typedef enum{
|
||||
M0RELAX, // normal moving
|
||||
M0FAST, // fast move to zero
|
||||
M0SLOW // slowest move from ESW
|
||||
} mvto0state;
|
||||
|
||||
typedef enum{
|
||||
STALL_NO, // moving OK
|
||||
STALL_ONCE, // Nstalled < limit
|
||||
STALL_STOP // Nstalled >= limit
|
||||
} t_stalled;
|
||||
|
||||
#ifdef EBUG
|
||||
static uint8_t stp[MOTORSNO] = {0};
|
||||
#endif
|
||||
|
||||
static t_stalled stallflags[MOTORSNO];
|
||||
|
||||
// motors' direction: 1 for positive, -1 for negative (we need it as could be reverse)
|
||||
static int8_t motdir[MOTORSNO];
|
||||
// direction of moving when stalled (forbid moving in that direction before go out of position)
|
||||
static int8_t stalleddir[MOTORSNO] = {0};
|
||||
// current position (in steps) by STP counter
|
||||
static volatile int32_t stppos[MOTORSNO] = {0};
|
||||
// previous position when check (set to current in start of moving)
|
||||
static int32_t prevstppos[MOTORSNO];
|
||||
// target stepper position
|
||||
static int32_t targstppos[MOTORSNO] = {0};
|
||||
// position to start deceleration
|
||||
static int32_t decelstartpos[MOTORSNO];
|
||||
// ESW reaction - local copy
|
||||
static uint8_t ESW_reaction[MOTORSNO];
|
||||
|
||||
// current speed
|
||||
static uint16_t curspeed[MOTORSNO];
|
||||
static uint16_t startspeed[MOTORSNO]; // speed when deceleration starts
|
||||
// ==1 to stop @ nearest step
|
||||
static uint8_t stopflag[MOTORSNO];
|
||||
// motor state
|
||||
static stp_state state[MOTORSNO];
|
||||
// move to zero state
|
||||
static mvto0state mvzerostate[MOTORSNO];
|
||||
|
||||
static int8_t Nstalled[MOTORSNO] = {0}; // counter of STALL
|
||||
|
||||
// lowest ARR value (highest speed), highest (lowest speed)
|
||||
//static uint16_t stphighARR[MOTORSNO];
|
||||
// microsteps=1<<ustepsshift
|
||||
static uint16_t ustepsshift[MOTORSNO];
|
||||
// amount of steps for full acceleration/deceleration
|
||||
static uint32_t accdecsteps[MOTORSNO];
|
||||
|
||||
// time when acceleration or deceleration starts
|
||||
static uint32_t Taccel[MOTORSNO] = {0};
|
||||
|
||||
// recalculate ARR according to new speed
|
||||
TRUE_INLINE void recalcARR(int i){
|
||||
uint32_t ARR = (((PCLK/(MOTORTIM_PSC+1)) / curspeed[i]) >> ustepsshift[i]) - 1;
|
||||
if(ARR < MOTORTIM_ARRMIN) ARR = MOTORTIM_ARRMIN;
|
||||
else if(ARR > 0xffff) ARR = 0xffff;
|
||||
mottimers[i]->ARR = ARR;
|
||||
curspeed[i] = (((PCLK/(MOTORTIM_PSC+1)) / (ARR+1)) >> ustepsshift[i]); // recalculate speed due to new val
|
||||
}
|
||||
|
||||
// run this function after each steppers parameters changing
|
||||
void init_steppers(){
|
||||
// init variables
|
||||
for(int i = 0; i < MOTORSNO; ++i){
|
||||
stalleddir[i] = 0; // clear old stall direction
|
||||
stopflag[i] = 0;
|
||||
motdir[i] = 0;
|
||||
curspeed[i] = 0;
|
||||
accdecsteps[i] = (the_conf.maxspd[i] * the_conf.maxspd[i]) / the_conf.accel[i] / 2;
|
||||
state[i] = STP_RELAX;
|
||||
ustepsshift[i] = MSB(the_conf.microsteps[i]);
|
||||
if(!the_conf.motflags[i].donthold) MOTOR_EN(i);
|
||||
else MOTOR_DIS(i);
|
||||
ESW_reaction[i] = the_conf.ESW_reaction[i];
|
||||
}
|
||||
}
|
||||
|
||||
// set absolute position of motor `i`
|
||||
errcodes setmotpos(uint8_t i, int32_t position){
|
||||
if(state[i] != STP_RELAX) return ERR_CANTRUN;
|
||||
if(position > (int32_t)the_conf.maxsteps[i] || position < -(int32_t)the_conf.maxsteps[i])
|
||||
return ERR_BADVAL; // too big position or zero
|
||||
if(position == stppos[i]) return ERR_OK;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
// get current position
|
||||
errcodes getpos(uint8_t i, int32_t *position){
|
||||
*position = stppos[i];
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
errcodes getremainsteps(uint8_t i, int32_t *position){
|
||||
*position = targstppos[i] - stppos[i];
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
// calculate acceleration/deceleration parameters for motor i
|
||||
static void calcacceleration(uint8_t i){
|
||||
switch(state[i]){ // do nothing in case of error/stopping
|
||||
case STP_ERR:
|
||||
case STP_RELAX:
|
||||
case STP_STALL:
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
int32_t delta = targstppos[i] - stppos[i];
|
||||
if(delta > 0){ // positive direction
|
||||
if(delta > 2*(int32_t)accdecsteps[i]){ // can move by trapezoid
|
||||
decelstartpos[i] = targstppos[i] - accdecsteps[i];
|
||||
}else{ // triangle speed profile
|
||||
decelstartpos[i] = stppos[i] + delta/2;
|
||||
}
|
||||
if(the_conf.motflags[i].reverse) MOTOR_CCW(i);
|
||||
else MOTOR_CW(i);
|
||||
}else{ // negative direction
|
||||
delta = -delta;
|
||||
if(delta > 2*(int32_t)accdecsteps[i]){ // can move by trapezoid
|
||||
decelstartpos[i] = targstppos[i] + accdecsteps[i];
|
||||
}else{ // triangle speed profile
|
||||
decelstartpos[i] = stppos[i] - delta/2;
|
||||
}
|
||||
if(the_conf.motflags[i].reverse) MOTOR_CW(i);
|
||||
else MOTOR_CCW(i);
|
||||
}
|
||||
if(state[i] != STP_MVSLOW){
|
||||
DBG("->accel");
|
||||
state[i] = STP_ACCEL;
|
||||
}
|
||||
startspeed[i] = curspeed[i];
|
||||
Taccel[i] = Tms;
|
||||
recalcARR(i);
|
||||
}
|
||||
|
||||
// check if end-switch is blocking the moving of i'th motor
|
||||
// @return TRUE if motor can't move
|
||||
static int esw_block(uint8_t i){
|
||||
int ret = FALSE;
|
||||
uint8_t s = ESW_state(i);
|
||||
if(s){ // ESW active
|
||||
switch(ESW_reaction[i]){
|
||||
case ESW_ANYSTOP: // stop motor in any direction
|
||||
ret = TRUE;
|
||||
break;
|
||||
case ESW_STOPMINUS: // stop only @ given direction
|
||||
if(motdir[i] == -1 && (s & 1)) ret = TRUE; // stop @ESW0
|
||||
if(motdir[i] == 1 && (s & 3)) ret = TRUE; // stop @ESW1
|
||||
break;
|
||||
default: // ESW_IGNORE
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// move to absolute position
|
||||
errcodes motor_absmove(uint8_t i, int32_t newpos){
|
||||
//if(i >= MOTORSNO) return ERR_BADPAR; // bad motor number
|
||||
int8_t dir = (newpos > stppos[i]) ? 1 : -1;
|
||||
switch(state[i]){
|
||||
case STP_ERR:
|
||||
case STP_RELAX:
|
||||
break;
|
||||
case STP_STALL:
|
||||
DBG("Move from STALL");
|
||||
if(dir == stalleddir[i]){
|
||||
DBG("Move to stalled direction!");
|
||||
return ERR_CANTRUN; // can't run into stalled direction
|
||||
}
|
||||
break;
|
||||
default: // moving state
|
||||
DBG("Is moving");
|
||||
return ERR_CANTRUN;
|
||||
}
|
||||
if(newpos > (int32_t)the_conf.maxsteps[i] || newpos < -(int32_t)the_conf.maxsteps[i] || newpos == stppos[i]){
|
||||
DBG("Too much steps");
|
||||
return ERR_BADVAL; // too big position or zero
|
||||
}
|
||||
motdir[i] = dir; // should be before limit switch check
|
||||
if(esw_block(i)){
|
||||
DBG("Block by ESW");
|
||||
return ERR_CANTRUN; // on end-switch
|
||||
}
|
||||
Nstalled[i] = (state[i] == STP_STALL) ? -(NSTALLEDMAX*4) : 0; // give some more chances to go out of stall state
|
||||
stopflag[i] = 0;
|
||||
targstppos[i] = newpos;
|
||||
prevstppos[i] = stppos[i];
|
||||
curspeed[i] = the_conf.minspd[i];
|
||||
state[i] = STP_ACCEL;
|
||||
calcacceleration(i);
|
||||
#ifdef EBUG
|
||||
USND("MOTOR"); USB_putbyte('0'+i);
|
||||
USND(" targstppos="); printi(targstppos[i]);
|
||||
USND(", decelstart="); printi(decelstartpos[i]);
|
||||
USND(", accdecsteps="); printu(accdecsteps[i]); newline();
|
||||
#endif
|
||||
MOTOR_EN(i);
|
||||
mottimers[i]->CR1 |= TIM_CR1_CEN; // start timer
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
// move i'th motor for relsteps
|
||||
errcodes motor_relmove(uint8_t i, int32_t relsteps){
|
||||
return motor_absmove(i, stppos[i] + relsteps);
|
||||
}
|
||||
|
||||
errcodes motor_relslow(uint8_t i, int32_t relsteps){
|
||||
errcodes e = motor_absmove(i, stppos[i] + relsteps);
|
||||
if(ERR_OK == e){
|
||||
DBG("-> MVSLOW");
|
||||
state[i] = STP_MVSLOW;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
// emergency stop and clear errors
|
||||
void emstopmotor(uint8_t i){
|
||||
switch(state[i]){
|
||||
case STP_ERR: // clear error state
|
||||
case STP_STALL:
|
||||
DBG("-> RELAX");
|
||||
state[i] = STP_RELAX;
|
||||
// fallthrough
|
||||
case STP_RELAX: // do nothing in stopping state
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
stopflag[i] = 1;
|
||||
}
|
||||
|
||||
stp_state getmotstate(uint8_t i){
|
||||
return state[i];
|
||||
}
|
||||
|
||||
// count steps @tim 14/15/16
|
||||
void addmicrostep(uint8_t i){
|
||||
static volatile uint16_t microsteps[MOTORSNO] = {0}; // current microsteps position
|
||||
if(esw_block(i)) stopflag[i] = 1; // turn on stop flag if end-switch was active
|
||||
if(++microsteps[i] == the_conf.microsteps[i]){
|
||||
microsteps[i] = 0;
|
||||
stppos[i] += motdir[i];
|
||||
uint8_t stop_at_pos = 0;
|
||||
if(motdir[i] > 0){
|
||||
if(stppos[i] >= targstppos[i]){ // reached stop position
|
||||
stop_at_pos = 1;
|
||||
}
|
||||
}else{
|
||||
if(stppos[i] <= targstppos[i]){
|
||||
stop_at_pos = 1;
|
||||
}
|
||||
}
|
||||
if(stopflag[i] || stop_at_pos){ // stop NOW
|
||||
mottimers[i]->CR1 &= ~TIM_CR1_CEN; // stop timer
|
||||
if(stopflag[i]) targstppos[i] = stppos[i]; // keep position (for keep flag)
|
||||
stopflag[i] = 0;
|
||||
if(the_conf.motflags[i].donthold)
|
||||
MOTOR_DIS(i); // turn off power
|
||||
if(stallflags[i] == STALL_STOP){
|
||||
stallflags[i] = STALL_NO;
|
||||
state[i] = STP_STALL;
|
||||
}else{
|
||||
state[i] = STP_RELAX;
|
||||
}
|
||||
#ifdef EBUG
|
||||
stp[i] = 1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EBUG
|
||||
#define TODECEL() do{state[i] = STP_DECEL; \
|
||||
startspeed[i] = curspeed[i]; \
|
||||
Taccel[i] = Tms; \
|
||||
USND("MOTOR"); USB_putbyte('0'+i); \
|
||||
USND(" -> DECEL@"); printi(stppos[i]); USND(", V="); printu(curspeed[i]); newline(); \
|
||||
}while(0)
|
||||
#else
|
||||
#define TODECEL() do{state[i] = STP_DECEL; \
|
||||
startspeed[i] = curspeed[i]; \
|
||||
Taccel[i] = Tms; \
|
||||
}while(0)
|
||||
#endif
|
||||
|
||||
// check state of i`th stepper
|
||||
static void chkstepper(int i){
|
||||
int32_t i32;
|
||||
static uint8_t stopctr[MOTORSNO] = {0}; // counters for encoders/position zeroing after stopping @ esw
|
||||
#ifdef EBUG
|
||||
if(stp[i]){
|
||||
stp[i] = 0;
|
||||
// motor state could be changed outside of interrupt, so return it to relax or leave in STALL
|
||||
state[i] = STP_RELAX;
|
||||
USND("MOTOR"); USB_putbyte('0'+i); USND(" stop @"); printi(stppos[i]);
|
||||
USND(", curstate="); printu(state[i]); newline();
|
||||
}
|
||||
#endif
|
||||
switch(state[i]){
|
||||
case STP_ACCEL: // acceleration to max speed
|
||||
//newspeed = curspeed[i] + dV[i];
|
||||
i32 = the_conf.minspd[i] + (the_conf.accel[i] * (Tms - Taccel[i])) / 1000;
|
||||
if(i32 >= the_conf.maxspd[i]){ // max speed reached -> move with it
|
||||
curspeed[i] = the_conf.maxspd[i];
|
||||
state[i] = STP_MOVE;
|
||||
#ifdef EBUG
|
||||
USND("MOTOR"); USB_putbyte('0'+i);
|
||||
USND(" -> MOVE@"); printi(stppos[i]); USND(", V="); printu(curspeed[i]); newline();
|
||||
#endif
|
||||
}else{ // increase speed
|
||||
curspeed[i] = i32;
|
||||
}
|
||||
recalcARR(i);
|
||||
// check position for triangle profile
|
||||
if(motdir[i] > 0){
|
||||
if(stppos[i] >= decelstartpos[i]){ // reached end of acceleration
|
||||
TODECEL();
|
||||
}
|
||||
}else{
|
||||
if(stppos[i] <= decelstartpos[i]){
|
||||
TODECEL();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STP_MOVE: // move @ constant speed until need to decelerate
|
||||
// check position
|
||||
if(motdir[i] > 0){
|
||||
if(stppos[i] >= decelstartpos[i]){ // reached start of deceleration
|
||||
TODECEL();
|
||||
}
|
||||
}else{
|
||||
if(stppos[i] <= decelstartpos[i]){
|
||||
TODECEL();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STP_DECEL:
|
||||
//newspeed = curspeed[i] - dV[i];
|
||||
i32 = startspeed[i] - (the_conf.accel[i] * (Tms - Taccel[i])) / 1000;
|
||||
if(i32 > the_conf.minspd[i]){
|
||||
curspeed[i] = i32;
|
||||
}else{
|
||||
curspeed[i] = the_conf.minspd[i];
|
||||
state[i] = STP_MVSLOW;
|
||||
#ifdef EBUG
|
||||
USND("MOTOR"); USB_putbyte('0'+i);
|
||||
USND(" -> MVSLOW@"); printi(stppos[i]); newline();
|
||||
#endif
|
||||
}
|
||||
recalcARR(i);
|
||||
break;
|
||||
default: // do nothing, check mvzerostate
|
||||
break;
|
||||
}
|
||||
switch(mvzerostate[i]){
|
||||
case M0FAST:
|
||||
if(state[i] == STP_RELAX || state[i] == STP_STALL){ // stopped -> move to +
|
||||
#ifdef EBUG
|
||||
USB_putbyte('M'); USB_putbyte('0'+i); USND("FAST: motor stopped\n");
|
||||
#endif
|
||||
if(ERR_OK != motor_relslow(i, 1000)){
|
||||
#ifdef EBUG
|
||||
USND("Can't move\n");
|
||||
#endif
|
||||
DBG("->ERR");
|
||||
state[i] = STP_ERR;
|
||||
mvzerostate[i] = M0RELAX;
|
||||
ESW_reaction[i] = the_conf.ESW_reaction[i];
|
||||
}else{
|
||||
mvzerostate[i] = M0SLOW;
|
||||
stopctr[i] = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case M0SLOW:
|
||||
if(0 == ESW_state(i)){ // moved out of limit switch - can stop
|
||||
emstopmotor(i);
|
||||
}
|
||||
if((state[i] == STP_RELAX || state[i] == STP_STALL) && ++stopctr[i] > 5){ // wait at least 50ms
|
||||
#ifdef EBUG
|
||||
USB_putbyte('M'); USB_putbyte('0'+i); USND("SLOW: motor stopped\n");
|
||||
#endif
|
||||
ESW_reaction[i] = the_conf.ESW_reaction[i];
|
||||
prevstppos[i] = targstppos[i] = stppos[i] = 0;
|
||||
mvzerostate[i] = M0RELAX;
|
||||
}
|
||||
break;
|
||||
default: // RELAX, STALL: do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
errcodes motor_goto0(uint8_t i){
|
||||
errcodes e = motor_absmove(i, -the_conf.maxsteps[i]);
|
||||
if(ERR_OK != e){
|
||||
if(!ESW_state(i)) return e; // not @ limit switch -> error
|
||||
}else ESW_reaction[i] = ESW_STOPMINUS;
|
||||
mvzerostate[i] = M0FAST;
|
||||
return e;
|
||||
}
|
||||
|
||||
// smooth motor stopping
|
||||
void stopmotor(uint8_t i){
|
||||
switch(state[i]){
|
||||
case STP_MVSLOW: // immeditially stop on slowest speed
|
||||
stopflag[i] = 1;
|
||||
return;
|
||||
break;
|
||||
case STP_MOVE: // stop only in moving states
|
||||
case STP_ACCEL:
|
||||
break;
|
||||
default: // do nothing in other states
|
||||
return;
|
||||
}
|
||||
int32_t newstoppos = stppos[i]; // calculate steps need for stop (we can be @acceleration phase!)
|
||||
int32_t add = (curspeed[i] * curspeed[i]) / the_conf.accel[i] / 2;
|
||||
if(motdir[i] > 0){
|
||||
newstoppos += add;
|
||||
if(newstoppos < (int32_t)the_conf.maxsteps[i]) targstppos[i] = newstoppos;
|
||||
}else{
|
||||
newstoppos -= add;
|
||||
if(newstoppos > -((int32_t)the_conf.maxsteps[i])) targstppos[i] = newstoppos;
|
||||
}
|
||||
TODECEL();
|
||||
}
|
||||
|
||||
void process_steppers(){
|
||||
static uint32_t Tlast = 0;
|
||||
if(Tms - Tlast < MOTCHKINTERVAL) return; // hit every 10ms
|
||||
Tlast = Tms;
|
||||
for(int i = 0; i < MOTORSNO; ++i){
|
||||
chkstepper(i);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t geteswreact(uint8_t i){
|
||||
return ESW_reaction[i];
|
||||
}
|
||||
@ -35,7 +35,7 @@ typedef enum{
|
||||
STP_MOVE, // 2 - moving with constant speed
|
||||
STP_MVSLOW, // 3 - moving with slowest constant speed (end of moving)
|
||||
STP_DECEL, // 4 - moving with deceleration
|
||||
STP_STALL, // 5 - stalled
|
||||
STP_STALL, // 5 - stalled (UNUSED)
|
||||
STP_ERR // 6 - wrong/error state
|
||||
} stp_state;
|
||||
|
||||
@ -43,18 +43,15 @@ typedef enum{
|
||||
enum{
|
||||
ESW_IGNORE, // don't stop @ end-switch
|
||||
ESW_ANYSTOP, // stop @ esw in any moving direction
|
||||
ESW_STOPMINUS, // stop only in negative moving
|
||||
ESW_STOPMINUS, // stop only when moving in given direction (e.g. to minus @ESW0)
|
||||
ESW_AMOUNT // number of records
|
||||
};
|
||||
|
||||
// find zero stages: fast -> 0, slow -> +, slow -> 0
|
||||
|
||||
void addmicrostep(uint8_t i);
|
||||
void encoders_UPD(uint8_t i);
|
||||
|
||||
void init_steppers();
|
||||
int32_t encoder_position(uint8_t i);
|
||||
int setencpos(uint8_t i, int32_t position);
|
||||
errcodes setmotpos(uint8_t i, int32_t position);
|
||||
|
||||
errcodes getpos(uint8_t i, int32_t *position);
|
||||
|
||||
@ -171,6 +171,7 @@ void USB_proc(){
|
||||
}
|
||||
break;
|
||||
default: // USB_STATE_CONNECTED - send next data portion
|
||||
if(!usbON) return;
|
||||
// if(!usbON) return; // WTF?
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
#define BUILD_NUMBER "30"
|
||||
#define BUILD_DATE "2023-02-16"
|
||||
#define BUILD_NUMBER "54"
|
||||
#define BUILD_DATE "2023-02-20"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user