fixed bugs in multistepper: eeprom in flash + adc, tested on TMC2130, but don't work on TMC2230

This commit is contained in:
Edward Emelianov
2023-02-24 23:29:34 +03:00
parent 1a8345d4f0
commit 59d8f8f515
18 changed files with 172 additions and 130 deletions

View File

@@ -77,7 +77,7 @@ void adc_setup(){
// ADC1: channels 1,2,3,4,16,18; ADC2: channels 1,10
ADC1->SMPR1 = ADC_SMPR1_SMP1 | ADC_SMPR1_SMP2 | ADC_SMPR1_SMP3 | ADC_SMPR1_SMP4;
ADC1->SMPR2 = ADC_SMPR2_SMP16 | ADC_SMPR2_SMP18;
// 4 conversions in group: 1->2->3->4->16->18
// 6 conversions in group: 1->2->3->4->16->18
ADC1->SQR1 = (1<<6) | (2<<12) | (3<<18) | (4<<24) | (NUMBER_OF_ADC1_CHANNELS-1);
ADC1->SQR2 = (16<<0) | (18<<6);
ADC2->SMPR1 = ADC_SMPR1_SMP1;
@@ -134,8 +134,7 @@ uint16_t getADCval(int nch){
// get voltage @input nch (V)
float getADCvoltage(int nch){
float v = getADCval(nch);
v *= getVdd();
float v = getADCval(nch) * 3.3;
v /= 4096.f; // 12bit ADC
#ifdef EBUG
DBG("v="); printf(v); newline();
@@ -157,7 +156,7 @@ float getMCUtemp(){
return(temperature);
}
// return Vdd (V)
// return ADC Vref (V)
float getVdd(){
float vdd = ((float) *VREFINT_CAL_ADDR) * 3.3f; // 3.3V
vdd /= getADCval(ADC_VREF);

View File

@@ -55,17 +55,18 @@ errcodes cu_accel(uint8_t _U_ par, int32_t _U_ *val){
if(ISSETTER(par)){
if(*val/the_conf.microsteps[n] > ACCELMAXSTEPS || *val < 1) return ERR_BADVAL;
the_conf.accel[n] = *val;
update_stepper(n);
}
*val = the_conf.accel[n];
return ERR_OK;
}
static const uint8_t extADCchnl[NUMBER_OF_EXT_ADC_CHANNELS] = {ADC_AIN0, ADC_AIN1, ADC_AIN2, ADC_AIN3};
// V*10
// V*100
errcodes cu_adc(uint8_t par, int32_t *val){
uint8_t n = PARBASE(par);
if(n > NUMBER_OF_EXT_ADC_CHANNELS - 1) return ERR_BADPAR;
float v = getADCvoltage(extADCchnl[n])*10.f;
float v = getADCvoltage(extADCchnl[n])*100.f;
*val = (int32_t)v;
return ERR_OK;
}
@@ -93,7 +94,9 @@ errcodes cu_emstop(uint8_t _U_ par, int32_t _U_ *val){
errcodes cu_eraseflash(uint8_t _U_ par, int32_t _U_ *val){
NOPARCHK(par);
if(erase_storage()) return ERR_CANTRUN;
if(ISSETTER(par)){
if(erase_storage(*val)) return ERR_BADVAL;
}else if(erase_storage(-1)) return ERR_CANTRUN;
return ERR_OK;
}
@@ -109,6 +112,7 @@ errcodes cu_eswreact(uint8_t _U_ par, int32_t _U_ *val){
if(ISSETTER(par)){
if(*val < 0 || *val > ESW_AMOUNT-1) return ERR_BADVAL;
the_conf.ESW_reaction[n] = *val;
update_stepper(n);
}
*val = geteswreact(n);
return ERR_OK;
@@ -188,6 +192,7 @@ errcodes cu_maxspeed(uint8_t _U_ par, int32_t _U_ *val){
if(ISSETTER(par)){
if(*val <= the_conf.minspd[n]) return ERR_BADVAL;
the_conf.maxspd[n] = getSPD(n, *val);
update_stepper(n);
}
*val = the_conf.maxspd[n];
return ERR_OK;
@@ -229,6 +234,7 @@ errcodes cu_microsteps(uint8_t _U_ par, int32_t _U_ *val){
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;
update_stepper(n);
}
*val = the_conf.microsteps[n];
return ERR_OK;
@@ -239,6 +245,7 @@ errcodes cu_minspeed(uint8_t _U_ par, int32_t _U_ *val){
if(ISSETTER(par)){
if(*val >= the_conf.maxspd[n]) return ERR_BADVAL;
the_conf.minspd[n] = getSPD(n, *val);
update_stepper(n);
}
*val = the_conf.minspd[n];
return ERR_OK;
@@ -248,6 +255,7 @@ 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);
update_stepper(n);
}
*(motflags_t*)val = the_conf.motflags[n];
return ERR_OK;
@@ -334,14 +342,14 @@ errcodes cu_usartstatus(uint8_t _U_ par, int32_t _U_ *val){
// V*10
errcodes cu_vdrive(uint8_t par, int32_t _U_ *val){
NOPARCHK(par);
float v = getADCvoltage(ADC_VDRIVE)*100.f;
float v = getADCvoltage(ADC_VDRIVE)*1000.f;
*val = (int32_t)v;
return ERR_OK;
}
errcodes cu_vfive(uint8_t par, int32_t *val){
NOPARCHK(par);
float v = getADCvoltage(ADC_VFIVE)*20.f;
float v = getADCvoltage(ADC_VFIVE)*200.f;
*val = (int32_t)v;
return ERR_OK;
}

View File

@@ -46,7 +46,7 @@ static uint32_t maxCnum = 1024 / sizeof(user_conf); // can't use blocksize here
,.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);
// don't write `static` here, or get error:
// 'memcpy' forming offset 8 is out of the bounds [0, 4] of object '__varsstart' with type 'uint32_t'
@@ -89,7 +89,7 @@ static int binarySearch(int r, const uint8_t *start, int stor_size){
*/
void flashstorage_init(){
if(FLASH_SIZE > 0 && FLASH_SIZE < 20000){
uint32_t flsz = FLASH_SIZE * FLASH_blocksize; // size in bytes
uint32_t flsz = FLASH_SIZE * 1024; // size in bytes
flsz -= (uint32_t)(&__varsstart) - FLASH_BASE;
maxCnum = flsz / sizeof(user_conf);
}
@@ -107,7 +107,7 @@ int store_userconf(){
// for binarySearch() checking that there's nothing more after it!
if(currentconfidx > (int)maxCnum - 3){ // there's no more place
currentconfidx = 0;
if(erase_flash(Flash_Data, NULL)) return 1;
if(erase_storage(-1)) return 1;
}else ++currentconfidx; // take next data position (0 - within first run after firmware flashing)
return write2flash((const void*)&Flash_Data[currentconfidx], &the_conf, sizeof(the_conf));
}
@@ -118,65 +118,81 @@ 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);
if(FLASH->SR & FLASH_SR_WRPERR){
return 1; // write protection
}
while(FLASH->SR & FLASH_SR_BSY) IWDG->KR = IWDG_REFRESH;
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR; // clear all flags
FLASH->CR |= FLASH_CR_PG;
const uint16_t *data = (const uint16_t*) wrdata;
volatile uint16_t *address = (volatile uint16_t*) start;
USB_sendstr("Start address="); printuhex((uint32_t)start); newline();
uint32_t i, count = (stor_size + 1) / 2;
for(i = 0; i < count; ++i){
IWDG->KR = IWDG_REFRESH;
*(volatile uint16_t*)(address + i) = data[i];
while (FLASH->SR & FLASH_SR_BSY);
while (FLASH->SR & FLASH_SR_BSY) IWDG->KR = IWDG_REFRESH;
if(*(volatile uint16_t*)(address + i) != data[i]){
USB_sendstr("DON'T MATCH!\n");
ret = 1;
break;
}
#ifdef EBUG
else{ USB_sendstr("Written "); printuhex(data[i]); newline();}
#endif
if(FLASH->SR & FLASH_SR_PGERR){
USB_sendstr("Prog err\n");
ret = 1; // program error - meet not 0xffff
break;
}
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR;
}
FLASH->CR |= FLASH_CR_LOCK; // lock it back
FLASH->CR &= ~(FLASH_CR_PG);
return ret;
}
/**
* @brief erase_flash - erase N pages of flash memory
* @param start - first address
* @param end - last address (or NULL if need to erase all flash remaining)
* @return 0 if succeed
*/
static int erase_flash(const void *start, const void *end){
// erase Nth page of flash storage (flash should be prepared!)
static int erase_pageN(int N){
int ret = 0;
uint32_t nblocks = 1, flsz = 0;
if(!end){ // erase all remaining
if(FLASH_SIZE > 0 && FLASH_SIZE < 20000){
flsz = FLASH_SIZE * FLASH_blocksize; // size in bytes
flsz -= (uint32_t)start - FLASH_BASE;
}
}else{ // erase a part
flsz = (uint32_t)end - (uint32_t)start;
#ifdef EBUG
USB_sendstr("Erase block #"); printu(N); newline();
#endif
FLASH->AR = (uint32_t)Flash_Data + N*FLASH_blocksize;
FLASH->CR |= FLASH_CR_STRT;
while(FLASH->SR & FLASH_SR_BSY) IWDG->KR = IWDG_REFRESH;
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*/
}
return ret;
}
// erase full storage (npage < 0) or its nth page; @return 0 if all OK
int erase_storage(int npage){
int ret = 0;
uint32_t end = 1, start = 0, flsz = 0;
if(FLASH_SIZE > 0 && FLASH_SIZE < 20000){
flsz = FLASH_SIZE * 1024; // size in bytes
flsz -= (uint32_t)Flash_Data - FLASH_BASE;
}
end = flsz / FLASH_blocksize;
if(end == 0 || end >= FLASH_SIZE) return 1;
if(npage > -1){ // erase only one page
if((uint32_t)npage >= end) return 1;
start = npage;
end = start + 1;
}
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;
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 */
/*USB_sendstr("size/block size/nblocks/FLASH_SIZE: "); printu(flsz);
USB_putbyte('/'); printu(FLASH_blocksize); USB_putbyte('/');
printu(nblocks); USB_putbyte('/'); printu(FLASH_SIZE); newline(); USB_sendall();*/
while(FLASH->SR & FLASH_SR_BSY) IWDG->KR = IWDG_REFRESH;
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR;
FLASH->CR |= FLASH_CR_PER;
for(uint32_t i = start; i < end; ++i){
if(erase_pageN(i)){
ret = 1;
FLASH->SR |= FLASH_SR_WRPERR; /* Clear the flag by software by writing it at 1*/
break;
}
}
@@ -184,9 +200,6 @@ static int erase_flash(const void *start, const void *end){
return ret;
}
int erase_storage(){
return erase_flash(Flash_Data, NULL);
}
int fn_dumpconf(uint32_t _U_ hash, char _U_ *args){ // "dumpconf" (3271513185)
#ifdef EBUG

View File

@@ -72,5 +72,5 @@ extern user_conf the_conf; // global user config (read from FLASH to RAM)
void flashstorage_init();
int store_userconf();
int erase_storage();
int erase_storage(int npage);

View File

@@ -18,6 +18,7 @@
#include "flash.h"
#include "hardware.h"
#include "steppers.h"
// Buttons: PA9, PA10, PF6, PD3, PD4, PD5, pullup (active - 0)
volatile GPIO_TypeDef* const BTNports[BTNSNO] = {GPIOA, GPIOA, GPIOF, GPIOD, GPIOD, GPIOD};
@@ -76,11 +77,11 @@ static IRQn_Type motirqs[MOTORSNO] = {
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);
val = ((ESWports[MOTno][0]->IDR & ESWpins[MOTno][0]) ? 1 : 0);
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;
val |= ((ESWports[MOTno][i]->IDR & ESWpins[MOTno][i]) ? 1 : 0) << i;
}
if(the_conf.motflags[MOTno].eswinv) val ^= 3;
return val;
@@ -221,9 +222,13 @@ static void setup_mpwm(int i){
}
void mottimers_setup(){
for(int i = 0; i < MOTORSNO; ++i) setup_mpwm(i);
}
void hw_setup(){
gpio_setup();
for(int i = 0; i < MOTORSNO; ++i) setup_mpwm(i);
mottimers_setup();
#ifndef EBUG
iwdg_setup();
#endif
@@ -232,34 +237,34 @@ void hw_setup(){
// timers for motors: 0:t15c1, 1:t16c1, 2:t17c1, 3:t2ch1, 4:t8ch1, 5:t4c1, 6:t1c1, 7:t3c3
void tim1_cc_isr(){
// addmicrostep(6);
addmicrostep(6);
TIM1->SR = 0;
}
void tim2_isr(){
// addmicrostep(3);
addmicrostep(3);
TIM2->SR = 0;
}
void tim3_isr(){
// addmicrostep(7);
addmicrostep(7);
TIM3->SR = 0;
}
void tim4_isr(){
// addmicrostep(5);
addmicrostep(5);
TIM4->SR = 0;
}
void tim8_cc_isr(){
// addmicrostep(4);
addmicrostep(4);
TIM8->SR = 0;
}
void tim1_brk_tim15_isr(){
// addmicrostep(0);
addmicrostep(0);
TIM15->SR = 0;
}
void tim1_up_tim16_isr(){
// addmicrostep(1);
addmicrostep(1);
TIM16->SR = 0;
}
void tim1_trg_com_tim17_isr(){
// addmicrostep(2);
addmicrostep(2);
TIM17->SR = 0;
}

View File

@@ -20,9 +20,10 @@
#include <stm32f3.h>
// PCLK frequency
// "PCLK" frequency
// really APB1=36M -> TIM2/3/4/6/7 f=72M, APB2=72M -> TIM1/8/15/16/17/20 f=72M
#ifndef PCLK
#define PCLK (48000000)
#define PCLK (72000000)
#endif
// motors' timer PSC = PCLK/Tfreq - 1, Tfreq=16MHz
@@ -33,8 +34,10 @@
// USB pullup: PA8
#define USBPU_port GPIOA
#define USBPU_pin (1<<8)
#define USBPU_ON() pin_clear(USBPU_port, USBPU_pin)
#define USBPU_OFF() pin_set(USBPU_port, USBPU_pin)
//#define USBPU_ON() pin_clear(USBPU_port, USBPU_pin)
//#define USBPU_OFF() pin_set(USBPU_port, USBPU_pin)
#define USBPU_ON() pin_set(USBPU_port, USBPU_pin)
#define USBPU_OFF() pin_clear(USBPU_port, USBPU_pin)
// temporary LED: PD9
#define LED_blink() pin_toggle(GPIOD, 1<<9)
@@ -86,4 +89,4 @@ extern volatile uint32_t Tms;
uint8_t ESW_state(uint8_t MOTno);
uint8_t MSB(uint16_t val);
void hw_setup();
void mottimers_setup();

View File

@@ -54,6 +54,8 @@ 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_dumpstates(_U_ uint32_t hash, _U_ char *args) WAL; // "dumpstates" (4235564367)
int fn_emstop(_U_ uint32_t hash, _U_ char *args) WAL; // "emstop" (2965919005)
int fn_eraseflash(_U_ uint32_t hash, _U_ char *args) WAL; // "eraseflash" (3177247267)
@@ -205,6 +207,9 @@ int parsecmd(const char *str){
case CMD_DUMPMOTFLAGS:
return fn_dumpmotflags(h, args);
break;
case CMD_DUMPSTATES:
return fn_dumpstates(h, args);
break;
case CMD_EMSTOP:
return fn_emstop(h, args);
break;

View File

@@ -35,6 +35,7 @@ int parsecmd(const char *cmdwargs);
#define CMD_DUMPCONF (3271513185)
#define CMD_DUMPERR (1223989764)
#define CMD_DUMPMOTFLAGS (36159640)
#define CMD_DUMPSTATES (4235564367)
#define CMD_EMSTOP (2965919005)
#define CMD_ERASEFLASH (3177247267)
#define CMD_ESW (2963094612)

View File

@@ -20,8 +20,9 @@
"dumpcmd - dump command codes\n"
"dumpconf - dump current configuration\n"
"dumpmotflags - dump motor flags' bits\n"
"dumpstates - dump motors' state codes\n"
"emstop[N] - emergency stop motor N or all\n"
"eraseflash - erase flash data storage\n"
"eraseflash [=N] - erase flash data storage (full or only N'th page of it)\n"
"esw[N] - G end-switches state\n"
"eswreactN - GS end-switches reaction (0 - ignore, 1 - stop@any, 2 - stop@zero)\n"
"gotoN - GS move motor to given absolute position\n"

View File

@@ -20,6 +20,7 @@ dumperr
dumpcmd
dumpconf
dumpmotflags
dumpstates
emstop
eraseflash
esw

View File

@@ -22,6 +22,7 @@
#include "flash.h"
#include "hardware.h"
#include "proto.h"
#include "steppers.h"
#include "usb.h"
#define MAXSTRLEN RBINSZ
@@ -40,9 +41,10 @@ int main(void){
StartHSI();
SysTick_Config((uint32_t)48000); // 1ms
}
//flashstorage_init();
hw_setup(); // GPIO, ADC, timers, watchdog etc.
USBPU_OFF(); // make a reconnection
flashstorage_init();
hw_setup(); // GPIO, ADC, timers, watchdog etc.
init_steppers();
USB_setup();
CAN_setup(the_conf.CANspeed);
adc_setup();
@@ -57,6 +59,7 @@ int main(void){
}
CAN_proc();
USB_proc();
process_steppers();
if(CAN_get_status() == CAN_FIFO_OVERRUN){
USB_sendstr("CAN bus fifo overrun occured!\n");
}

View File

@@ -448,6 +448,24 @@ int fn_dumperr(uint32_t _U_ hash, char _U_ *args){ // "dumperr" (1223989764)
return RET_GOOD;
}
static const char* motstates[STP_STATE_AMOUNT] = {
[STP_RELAX] = "relax",
[STP_ACCEL] = "acceleration",
[STP_MOVE] = "moving",
[STP_MVSLOW] = "moving at lowest speed",
[STP_DECEL] = "deceleration",
[STP_STALL] = "stalled (not used here!)",
[STP_ERR] = "error"
};
int fn_dumpstates(uint32_t _U_ hash, char _U_ *args){ // "dumpstates" (4235564367)
USND("Motor's state codes:");
for(int i = 0; i < STP_STATE_AMOUNT; ++i){
printu(i); USB_sendstr(" - ");
USB_sendstr(motstates[i]); newline();
}
return RET_GOOD;
}
int fn_canid(uint32_t _U_ hash, char *args){ // "canid" (2040257924)
if(args && *args){
int good = FALSE;
@@ -481,13 +499,13 @@ static int canusb_function(uint32_t hash, char *args){
return RET_GOOD;
}
par = (uint8_t) N;
n = strchr(n, '=');
if(n){
const char *nxt = getnum(n+1, &N);
if(nxt != n){ // give flag issetter
val = (int32_t) N;
par |= SETTERFLAG;
}
}
n = strchr(n, '=');
if(n){
++n;
const char *nxt = getint(n, &val);
if(nxt != n){ // set setter flag
par |= SETTERFLAG;
}
}
}
@@ -521,7 +539,7 @@ static int canusb_function(uint32_t hash, char *args){
USB_putbyte('='); USB_sendstr(u2str(getADCval(par)));
f = getADCvoltage(par);
USB_sendstr("\nADCv");USB_putbyte('0'+par);
USB_putbyte('='); USB_sendstr(float2str(f, 1));
USB_putbyte('='); USB_sendstr(float2str(f, 2));
newline();
return RET_GOOD;
break;

View File

@@ -30,22 +30,12 @@ typedef enum{
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)
@@ -67,8 +57,6 @@ 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
@@ -88,20 +76,26 @@ TRUE_INLINE void recalcARR(int i){
curspeed[i] = (((PCLK/(MOTORTIM_PSC+1)) / (ARR+1)) >> ustepsshift[i]); // recalculate speed due to new val
}
// update stepper's settings
void update_stepper(uint8_t i){
if(i >= MOTORSNO) return;
accdecsteps[i] = (the_conf.maxspd[i] * the_conf.maxspd[i]) / the_conf.accel[i] / 2;
ustepsshift[i] = MSB(the_conf.microsteps[i]);
ESW_reaction[i] = the_conf.ESW_reaction[i];
}
// run this function after each steppers parameters changing
void init_steppers(){
mottimers_setup(); // reinit timers
// 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];
update_stepper(i);
}
}
@@ -176,7 +170,7 @@ static int esw_block(uint8_t i){
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
if(motdir[i] == 1 && (s & 2)) ret = TRUE; // stop @ESW1
break;
default: // ESW_IGNORE
break;
@@ -194,11 +188,6 @@ errcodes motor_absmove(uint8_t i, int32_t newpos){
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");
@@ -213,7 +202,6 @@ errcodes motor_absmove(uint8_t i, int32_t newpos){
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];
@@ -221,10 +209,10 @@ errcodes motor_absmove(uint8_t i, int32_t newpos){
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();
USB_sendstr("MOTOR"); USB_putbyte('0'+i);
USB_sendstr(" targstppos="); printi(targstppos[i]);
USB_sendstr(", decelstart="); printi(decelstartpos[i]);
USB_sendstr(", accdecsteps="); printu(accdecsteps[i]); newline();
#endif
MOTOR_EN(i);
mottimers[i]->CR1 |= TIM_CR1_CEN; // start timer
@@ -288,12 +276,7 @@ void addmicrostep(uint8_t i){
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;
}
state[i] = STP_RELAX;
#ifdef EBUG
stp[i] = 1;
#endif
@@ -305,8 +288,8 @@ void addmicrostep(uint8_t i){
#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(); \
USB_sendstr("MOTOR"); USB_putbyte('0'+i); \
USB_sendstr(" -> DECEL@"); printi(stppos[i]); USB_sendstr(", V="); printu(curspeed[i]); newline(); \
}while(0)
#else
#define TODECEL() do{state[i] = STP_DECEL; \
@@ -322,22 +305,22 @@ static void chkstepper(int i){
#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
// motor state could be changed outside of interrupt, so return it to relax
state[i] = STP_RELAX;
USND("MOTOR"); USB_putbyte('0'+i); USND(" stop @"); printi(stppos[i]);
USND(", curstate="); printu(state[i]); newline();
USB_sendstr("MOTOR"); USB_putbyte('0'+i); USB_sendstr(" stop @"); printi(stppos[i]);
USB_sendstr(", V="); printu(curspeed[i]);
USB_sendstr(", 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();
USB_sendstr("MOTOR"); USB_putbyte('0'+i);
USB_sendstr(" -> MOVE@"); printi(stppos[i]); USB_sendstr(", V="); printu(curspeed[i]); newline();
#endif
}else{ // increase speed
curspeed[i] = i32;
@@ -375,8 +358,8 @@ static void chkstepper(int i){
curspeed[i] = the_conf.minspd[i];
state[i] = STP_MVSLOW;
#ifdef EBUG
USND("MOTOR"); USB_putbyte('0'+i);
USND(" -> MVSLOW@"); printi(stppos[i]); newline();
USB_sendstr("MOTOR"); USB_putbyte('0'+i);
USB_sendstr(" -> MVSLOW@"); printi(stppos[i]); newline();
#endif
}
recalcARR(i);
@@ -388,11 +371,11 @@ static void chkstepper(int 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");
USB_putbyte('M'); USB_putbyte('0'+i); USB_sendstr("FAST: motor stopped\n");
#endif
if(ERR_OK != motor_relslow(i, 1000)){
#ifdef EBUG
USND("Can't move\n");
USND("Can't move");
#endif
DBG("->ERR");
state[i] = STP_ERR;
@@ -410,7 +393,7 @@ static void chkstepper(int 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");
USB_putbyte('M'); USB_putbyte('0'+i); USND("SLOW: motor stopped");
#endif
ESW_reaction[i] = the_conf.ESW_reaction[i];
prevstppos[i] = targstppos[i] = stppos[i] = 0;

View File

@@ -36,7 +36,8 @@ typedef enum{
STP_MVSLOW, // 3 - moving with slowest constant speed (end of moving)
STP_DECEL, // 4 - moving with deceleration
STP_STALL, // 5 - stalled (UNUSED)
STP_ERR // 6 - wrong/error state
STP_ERR , // 6 - wrong/error state
STP_STATE_AMOUNT
} stp_state;
// end-switches reaction
@@ -52,8 +53,9 @@ enum{
void addmicrostep(uint8_t i);
void init_steppers();
errcodes setmotpos(uint8_t i, int32_t position);
void update_stepper(uint8_t i);
errcodes setmotpos(uint8_t i, int32_t position);
errcodes getpos(uint8_t i, int32_t *position);
errcodes getremainsteps(uint8_t i, int32_t *position);
errcodes motor_absmove(uint8_t i, int32_t abssteps);

View File

@@ -31,7 +31,7 @@
#define STR(s) STR_HELPER(s)
#ifdef EBUG
#define DBG(str) do{USB_sendstr(__FILE__ " (L" STR(__LINE__) "): " str);}while(0)
#define DBG(str) do{USB_sendstr(__FILE__ " (L" STR(__LINE__) "): " str); newline();}while(0)
#else
#define DBG(str)
#endif

View File

@@ -1,2 +1,2 @@
#define BUILD_NUMBER "56"
#define BUILD_DATE "2023-02-21"
#define BUILD_NUMBER "80"
#define BUILD_DATE "2023-02-24"