Fix error in CAN speed calculation

This commit is contained in:
eddyem 2020-04-30 01:18:39 +03:00
parent 131f6fab44
commit bc7a9aacc5
13 changed files with 524 additions and 45 deletions

View File

@ -145,7 +145,7 @@ void CAN_setup(uint16_t speed){
CAN->MCR &=~ CAN_MCR_SLEEP; /* (3) */
CAN->MCR |= CAN_MCR_ABOM; /* allow automatically bus-off */
CAN->BTR |= 2 << 20 | 3 << 16 | (6000/speed) << 0; /* (4) */
CAN->BTR |= 2 << 20 | 3 << 16 | (6000/speed - 1); /* (4) */
CAN->MCR &=~ CAN_MCR_INRQ; /* (5) */
tmout = 16000000;
while((CAN->MSR & CAN_MSR_INAK)==CAN_MSR_INAK) if(--tmout == 0) break; /* (6) */

View File

@ -46,9 +46,13 @@ static uint32_t maxCnum = FLASH_BLOCK_SIZE / sizeof(user_conf);
#define USERCONF_INITIALIZER { \
.userconf_sz = sizeof(user_conf) \
,.defflags = 0 \
,.defflags.reverse = 0 \
,.CANspeed = 100 \
,.driver_type = DRV_NONE \
,.microsteps = 16 \
,.accdecsteps = 100 \
,.motspd = 10 \
,.maxsteps = 50000 \
}
static int erase_flash(const void*, const void*);
@ -214,7 +218,6 @@ static int erase_flash(const void *start, const void *end){
void dump_userconf(){
SEND("userconf_addr="); printuhex((uint32_t)Flash_Data);
SEND("\nuserconf_sz="); printu(the_conf.userconf_sz);
SEND("\nflags="); printuhex(the_conf.defflags);
SEND("\nCANspeed="); printu(the_conf.CANspeed);
SEND("\ndriver_type=");
const char *p = "NONE";
@ -230,6 +233,12 @@ void dump_userconf(){
break;
}
SEND(p);
SEND("\nmicrosteps="); printu(the_conf.microsteps);
SEND("\naccdecsteps="); printu(the_conf.accdecsteps);
SEND("\nmotspd="); printu(the_conf.motspd);
SEND("\nmaxsteps="); printu(the_conf.maxsteps);
//flags
SEND("\nreverse="); bufputchar('0' + the_conf.defflags.reverse);
newline();
sendbuf();
}

View File

@ -30,13 +30,21 @@
#define FLASH_SIZE_REG ((uint32_t)0x1FFFF7CC)
#define FLASH_SIZE *((uint16_t*)FLASH_SIZE_REG)
typedef struct{
uint8_t reverse : 1;
} defflags_t;
/*
* struct to save user configurations
*/
typedef struct __attribute__((packed, aligned(4))){
uint32_t maxsteps; // maximal amount of steps from ESW0 to EWS3
uint16_t userconf_sz; // "magick number"
uint16_t CANspeed; // default CAN speed
uint8_t defflags; // default flags
uint16_t microsteps; // microsteps amount per step
uint16_t accdecsteps; // amount of steps need for full acceleration/deceleration cycle
uint16_t motspd; // max motor speed ([3000 / motspd] steps per second)
defflags_t defflags; // default flags
uint8_t driver_type; // user's settings: type of stepper's driver
} user_conf;

View File

@ -18,6 +18,8 @@
#include "hardware.h"
TIM_TypeDef *TIMx = TIM15; // stepper's timer
static uint8_t brdADDR = 0;
void Jump2Boot(){
@ -81,7 +83,7 @@ void gpio_setup(){
| RCC_AHBENR_DMAEN;
// setup pins need @start: Vio_ON (PF0, opendrain), ~FAULT (PF1, floating IN),
// ~SLEEP (PC15, pushpull), DIR (PA4, pushpull), ~EN (PC13, pushpull)
// ~CS, microstepping2, (PC14, pushpull
// ~CS, microstepping2, (PC14, pushpull)
// PA8 - Tx/Rx
// PB12..15 - board address, pullup input; PB0..2, PB10 - ESW, pullup inputs (inverse)
VIO_OFF();
@ -115,6 +117,22 @@ void gpio_setup(){
brdADDR = READ_BRD_ADDR();
}
// PA3 (STEP): TIM15_CH2; 48MHz -> 48kHz
void timer_setup(){
RCC->APB2ENR |= RCC_APB2ENR_TIM15EN; // enable clocking
TIM15->CR1 &= ~TIM_CR1_CEN; // turn off timer
TIM15->CCMR1 = TIM_CCMR1_OC2M_2; // Force inactive
TIM15->PSC = 999;
TIM15->CCER = TIM_CCER_CC2E;
TIM15->CCR1 = 1; // very short pulse
TIM15->ARR = 1000;
// enable IRQ & update values
TIM15->EGR = TIM_EGR_UG;
TIM15->DIER = TIM_DIER_CC2IE;
NVIC_EnableIRQ(TIM15_IRQn);
NVIC_SetPriority(TIM15_IRQn, 0);
}
uint8_t refreshBRDaddr(){
return (brdADDR = READ_BRD_ADDR());
}

View File

@ -68,14 +68,28 @@
#define RESET_UST2() do{GPIOC->BRR = 1<<14;}while(0)
#define CS_ACTIVE() do{GPIOC->BRR = 1<<14;}while(0)
#define CS_PASSIVE() do{GPIOC->BSRR = 1<<14;}while(0)
// microstepping0 (PA7), 1 (PA5) - set PP
#define UST01_CFG_PP() do{GPIOA->MODER = (GPIOA->MODER & ~(GPIO_MODER_MODER5|GPIO_MODER_MODER7)) | (GPIO_MODER_MODER5_O|GPIO_MODER_MODER7_O);}while(0)
#define SET_UST0() do{GPIOA->BSRR = 1<<7;}while(0)
#define SET_UST1() do{GPIOA->BSRR = 1<<5;}while(0)
#define RESET_UST0() do{GPIOA->BRR = 1<<7;}while(0)
#define RESET_UST1() do{GPIOA->BRR = 1<<5;}while(0)
// end-switches state
#define ESW_STATE() ((GPIOB->IDR & 0x07) | ((GPIOB->IDR>>7) & 0x08))
// configure ~CS as PP output
//#define CS_CFG_OUT() do{GPIOC->MODER = (GPIOC->MODER&~GPIO_MODER_MODER14) | GPIO_MODER_MODER14_O; }while(0)
// ~CS as floating input
;
// Vio_ON, PF0 (inverse)
#define VIO_ON() do{GPIOF->BRR = 1;}while(0)
#define VIO_OFF() do{GPIOF->BSRR = 1;}while(0)
// turn off timer of STEPS pin
#define STEP_TIMER_OFF() do{TIM15->CR1 &= ~TIM_CR1_CEN;}while(0)
// timer for stepper
extern TIM_TypeDef *TIMx;
#define timer_isr tim15_isr
extern volatile uint32_t Tms;
void Jump2Boot();
@ -84,4 +98,6 @@ void iwdg_setup();
uint8_t getBRDaddr();
uint8_t refreshBRDaddr();
void sleep(uint16_t ms);
void timer_setup();
#endif // __HARDWARE_H__

View File

@ -24,6 +24,7 @@
#include "flash.h"
#include "hardware.h"
#include "proto.h"
#include "steppers.h"
#include "usart.h"
#include "usb.h"
#include "usb_lib.h"
@ -81,7 +82,7 @@ static char *get_USB(){
}
int main(void){
uint32_t lastT = 0;
uint32_t lastT = 0, ostctr = 0;
sysreset();
SysTick_Config(6000, 1);
gpio_setup(); // + read board address
@ -120,6 +121,11 @@ int main(void){
}
IWDG->KR = IWDG_REFRESH;
can_messages_proc();
if(ostctr != Tms){ // check steppers not more than once in 1ms
ostctr = Tms;
stp_process();
}
}
return 0;
}

View File

@ -192,14 +192,45 @@ TRUE_INLINE void userconf_manip(char *txt){
}
break;
default:
SEND("Wrong argument of userconf manipulation: ");
SEND(txt);
SEND("\nUserconf commands:\n"
"d - userconf dump\n"
"s - userconf store\n"
);
}
}
TRUE_INLINE void setdefflags(char *txt){
const char *needar = "Need argument 0 or 1 for flag";
txt = omit_spaces(txt);
char ch = *txt;
++txt;
uint32_t U;
if(txt == getnum(txt, &U)){
SEND(needar);
return;
}
switch(ch){
case 'r':
if(U > 1){
SEND(needar);
return;
}
the_conf.defflags.reverse = U&1;
break;
default:
SEND("\nFlag commands:"
"r - set/clear reverse\n"
);
}
}
// a set of setters for user_conf
TRUE_INLINE void setters(char *txt){
uint32_t U;
uint8_t u8;
const char *drvshould = "Driver type should be one of: 2130, 4988, 8825";
const char *usshould = "Microsteps amount is a power of two: 1..512";
const char *motspdshould = "Motor speed should be from 2 to " STR(0xffff/LOWEST_SPEED_DIV);
txt = omit_spaces(txt);
if(!*txt){
SEND("Setters need more arguments");
@ -207,6 +238,21 @@ TRUE_INLINE void setters(char *txt){
}
char *nxt = getnum(txt + 1, &U);
switch(*txt){
case 'a': // accdecsteps
if(nxt == txt + 1){
SEND("No accdecsteps value given");
return;
}
if(U < ACCDECSTEPS_MIN || U > ACCDECSTEPS_MAX){
SEND("The value should be from" STR(ACCDECSTEPS_MIN) " to " STR(ACCDECSTEPS_MAX));
return;
}
if(the_conf.accdecsteps != (uint16_t) U){
the_conf.accdecsteps = (uint16_t) U;
userconf_changed = 1;
SEND("Set accdecsteps to "); printu(U);
}
break;
case 'c': // set CAN speed
if(nxt == txt + 1){
SEND("No CAN speed given");
@ -222,54 +268,144 @@ TRUE_INLINE void setters(char *txt){
}
if(the_conf.CANspeed != (uint16_t)U){
the_conf.CANspeed = (uint16_t)U;
SEND("Set CAN speed to "); printu(U);
userconf_changed = 1;
}
break;
default:
SEND("Wrong argument of setters: ");
SEND(txt);
}
}
TRUE_INLINE void driver_commands(char *txt){
uint32_t U;
char *nxt;
const char *drvshould = "Driver type should be one of: 2130, 4988, 8825";
txt = omit_spaces(txt);
if(!*txt){
SEND("Driver commands need more arguments");
return;
}
switch(*txt){
case 'i': // init
initDriver();
break;
case 's': // set type
nxt = getnum(txt + 1, &U);
case 'd': // set driver type
if(nxt == txt+1){
SEND(drvshould);
break;
}
u8 = DRV_NONE;
switch(U){
case 2130:
the_conf.driver_type = DRV_2130;
u8 = DRV_2130;
SEND("TMC2130");
break;
case 4988:
the_conf.driver_type = DRV_4988;
u8 = DRV_4988;
SEND("A4988");
break;
case 8825:
the_conf.driver_type = DRV_8825;
u8 = DRV_8825;
SEND("DRV8825");
break;
default:
SEND(drvshould);
}
if(the_conf.driver_type != u8){
the_conf.driver_type = u8;
userconf_changed = 1;
}
break;
case 'F':
setdefflags(txt+1);
break;
case 'm': // microsteps
if(nxt == txt + 1){ // no number
SEND(usshould); break;
}
if(U < 1 || U > getMaxUsteps() || (U & (U-1)) != 0){ // U over of range or not power of two
SEND(usshould); break;
}
if(the_conf.microsteps != (uint16_t)U){
the_conf.microsteps = (uint16_t)U;
userconf_changed = 1;
SEND("Set microsteps to "); printu(U);
}
break;
case 'M': // maxsteps
if(nxt == txt + 1 || U > INT32_MAX){
SEND("Enter number from 0 (infinity) to INT32_MAX"); break;
}
if(U != the_conf.maxsteps){
the_conf.maxsteps = U;
userconf_changed = 1;
}
break;
case 's': // motor speed
if(nxt == txt + 1 || U < 2 || U > (0xffff/LOWEST_SPEED_DIV)){ // no number
SEND(motspdshould); break;
}
if(the_conf.motspd != (uint16_t)U){
the_conf.motspd = (uint16_t)U;
userconf_changed = 1;
SEND("Set motspd to "); printu(U);
}
break;
default:
SEND("Wrong argument of driver commands: ");
SEND(txt);
SEND("\nSetters commands:\n"
"a - set accdecsteps\n"
"c - set default CAN speed\n"
"d - set driver type\n"
"F - set flags"
"m - set microsteps\n"
"M - set maxsteps\n"
"s - set motspd\n"
);
}
}
TRUE_INLINE void driver_commands(char *txt){
txt = omit_spaces(txt);
if(!*txt){
SEND("Driver commands need more arguments");
return;
}
char cmd = *txt++;
txt = omit_spaces(txt);
uint32_t U;
int8_t sign = 1;
if(*txt == '-'){
++txt;
sign = -1;
}
char *nxt = getnum(txt, &U);
stp_status st;
switch(cmd){
case 'e':
SEND("ESW=");
printu(ESW_STATE());
break;
case 'i': // init
initDriver();
break;
case 'm':
if(nxt == txt + 1 || U > (INT32_MAX-1)){
SEND("Give right steps amount: from -INT32_MAX to INT32_MAX");
return;
}
if(sign > 0) st = stp_move((int32_t)U);
else st = stp_move(-(int32_t)U);
switch(st){
case STPS_ACTIVE:
SEND("IsMoving");
break;
case STPS_ONESW:
SEND("OnEndSwitch");
break;
case STPS_ZEROMOVE:
SEND("ZeroMove");
break;
case STPS_TOOBIG:
SEND("TooBigNumber");
break;
default:
SEND("Move to given steps amount");
}
break;
case 's':
stp_stop();
SEND("Stop motor");
break;
default:
SEND("\nDriver commands:\n"
"e - end-switches state\n"
"i - init stepper driver (8825, 4988, 2130)\n"
"m - move N steps\n"
"s - stop\n"
);
}
}
@ -363,18 +499,16 @@ void cmd_parser(char *txt, uint8_t isUSB){
"a - get raw ADC values\n"
"b - switch to bootloader\n"
"d - dump userconf\n"
"Di - init stepper driver (8825, 4988, 2130)\n"
"Ds - set driver type\n"
"D? - stepper driver commands\n"
"g - get board address\n"
"j - get MCU temperature\n"
"k - get U values\n"
"m - start/stop monitoring CAN bus\n"
"s - send data over CAN: s ID [byte0..7]\n"
"S? - parameter setters\n"
"t - send test sequence over RS-485\n"
"T - print current time\n"
"Sc - set default CAN speed\n"
"Ud - userconf dump\n"
"Us - userconf store\n"
"U? - options for user configuration\n"
);
break;
}

View File

@ -22,6 +22,28 @@
static drv_type driver = DRV_NONE;
// maximum number of microsteps per driver
static const uint16_t maxusteps[] = {
[DRV_NONE] = 0,
[DRV_NOTINIT] = 0,
[DRV_MAILF] = 0,
[DRV_8825] = 32,
[DRV_4988] = 16,
[DRV_2130] = 256
};
// amount of steps need for full acceleration/deceleration cycle
#define ACCDECSTEPS (the_conf.accdecsteps)
// amount of microsteps in each step
#define USTEPS (the_conf.microsteps)
int32_t mot_position = -1; // current position of motor (from zero endswitch, -1 means inactive)
uint32_t steps_left = 0; // amount of steps left
stp_state state = STP_SLEEP;// current state of motor
// ARR register values: low (max speed), high (min speed = 10% from max), step (1/50(hi-lo))
static uint16_t stplowarr, stphigharr, stpsteparr;
static int8_t dir = 0; // moving direction: -1 (negative) or 1 (positive)
/**
* @brief checkDrv - test if driver connected
*/
@ -42,12 +64,16 @@ static void checkDrv(){
sleep(2);
// Check is ~SLEEP is in air
oldstate = SLP_STATE();
#ifdef EBUG
if(oldstate) MSG("SLP=1\n"); else MSG("SLP=0\n");
#endif
SLEEP_OFF(); SLP_CFG_OUT(); // sleep -> 1
sleep(2);
SLP_CFG_IN();
sleep(2);
#ifdef EBUG
if(SLP_STATE()) MSG("SLP=1\n"); else MSG("SLP=0\n");
#endif
if(SLP_STATE() != oldstate){
MSG("~SLP is in air\n");
if(driver != DRV_2130){
@ -63,13 +89,17 @@ static void checkDrv(){
EN_CFG_IN();
sleep(2);
oldstate = EN_STATE();
#ifdef EBUG
if(oldstate) MSG("EN=1\n"); else MSG("EN=0\n");
#endif
DRV_DISABLE(); // EN->1
EN_CFG_OUT();
sleep(2);
EN_CFG_IN();
sleep(2);
#ifdef EBUG
if(EN_STATE()) MSG("EN=1\n"); else MSG("EN=0\n");
#endif
if(oldstate != EN_STATE()){
MSG("~EN is in air\n");
driver = DRV_NONE;
@ -86,6 +116,47 @@ ret:
#endif
}
static drv_type ini2130(){ // init 2130: SPI etc.
if(driver != DRV_2130) return DRV_MAILF;
;
return DRV_MAILF;
}
static drv_type ini4988_8825(){ // init 4988 or 8825
if(driver != DRV_4988 && driver != DRV_8825){
MSG("Wrong drv\n");
return DRV_MAILF;
}
if(the_conf.microsteps > maxusteps[driver]){
SEND("Wrong microstepping settings\n");
return DRV_MAILF;
}
if(the_conf.microsteps == 0){
SEND("Configure microstepping first\n");
return DRV_MAILF;
}
// init microstepping pins and set config
UST01_CFG_PP();
uint8_t PINS = 0;
if(the_conf.microsteps == 16 && driver == DRV_4988) PINS = 7; // microstepping settings for 4988 in 1/16 differs from 8825
else PINS = (uint8_t)__builtin_ctz(the_conf.microsteps);
#ifdef EBUG
SEND("Microstep PINS=");
printu(PINS);
newline(); sendbuf();
#endif
// now PINS is M0..M2 settings
if(PINS & 1) SET_UST0(); else RESET_UST0();
if(PINS & 2) SET_UST1(); else RESET_UST1();
if(PINS & 4) SET_UST2(); else RESET_UST2();
// turn on timer
timer_setup();
// recalculate defaults
stp_chspd();
SEND("Init OK\n");
return driver;
}
/**
* @brief initDriver - try to init driver
* @return driver type
@ -93,12 +164,179 @@ ret:
drv_type initDriver(){
if(driver != DRV_NOTINIT){ // reset all settings
MSG("clear GPIO & other setup\n");
STEP_TIMER_OFF();
// TODO: turn off SPI & timer
gpio_setup(); // reset pins control
}
driver = the_conf.driver_type;
checkDrv();
if(driver == DRV_NONE) return driver;
// TODO: some stuff here
if(driver > DRV_MAX-1) return (driver = DRV_NONE);
MSG("init pins\n");
switch(driver){
case DRV_2130:
return ini2130();
break;
case DRV_4988:
case DRV_8825:
return ini4988_8825();
break;
default:
SEND("Set driver type in config\n");
return driver; // bad driver type
}
return driver;
}
uint16_t getMaxUsteps(){
if(driver > DRV_MAX-1) return 0;
return maxusteps[driver];
}
void stp_chspd(){
int i;
for(i = 0; i < 2; ++i){
uint16_t spd = the_conf.motspd;
stplowarr = spd;
stphigharr = spd * LOWEST_SPEED_DIV;
stpsteparr = (spd * (LOWEST_SPEED_DIV - 1)) / ((uint16_t)ACCDECSTEPS) + 1;
}
}
// check end-switches for stepper motors
void stp_process(){
// check end-switches; ESW0&ESW3 stops motor
uint8_t esw = ESW_STATE();
switch(state){
case STP_MOVE0: // move towards ESW0
state = STP_SLEEP;
stp_move(-the_conf.maxsteps); // won't move if the_conf.maxsteps == 0
break;
case STP_MOVE1: // move towards ESW3
state = STP_SLEEP;
stp_move(the_conf.maxsteps);
break;
case STP_ACCEL: // @ any move check esw
case STP_DECEL:
case STP_MOVE:
case STP_MVSLOW:
if((esw&1) && dir == -1){ // move through ESW0
state = STP_STOPZERO; // stop @ end-switch
}else if((esw&8) && dir == 1){ // move through ESW3
state = STP_STOP; // stop @ ESW3
}
break;
default: // stopping states - do nothing
break;
}
}
// move motor to `steps` steps, @return 0 if all OK
stp_status stp_move(int32_t steps){
if(state != STP_SLEEP && state != STP_MOVE0 && state != STP_MOVE1) return STPS_ACTIVE;
if(steps == 0)
return STPS_ZEROMOVE;
if(the_conf.maxsteps && steps > (int32_t)the_conf.maxsteps) return STPS_TOOBIG;
int8_t d;
if(steps < 0){
d = -1;
steps = -steps;
}else d = 1; // positive direction
// check end-switches
uint8_t esw = ESW_STATE();
if(((esw&1) && d == -1) || ((esw&8) && d == 1)) return STPS_ONESW; // can't move through esw
dir = d;
// change value of DIR pin
if(the_conf.defflags.reverse){
if(d>0)
SET_DIR();
else
CLEAR_DIR();
}else{
if(d>0)
CLEAR_DIR();
else
SET_DIR();
}
// turn on driver, EN=0
DRV_ENABLE();
steps_left = (uint32_t)steps;
// setup timer & start it
TIMx->ARR = stphigharr;
TIMx->CCMR1 = TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1; // PWM mode 1: active->inacive, preload enable
TIMx->CR1 |= TIM_CR1_CEN;
if(steps < ACCDECSTEPS*2) state = STP_MVSLOW; // move without acceleration
else state = STP_ACCEL; // move with acceleration
return STPS_ALLOK;
}
// change ARR value
void stp_chARR(uint32_t val){
if(val < 2) val = 2;
TIMx->ARR = (uint32_t)val;
}
void stp_stop(){ // stop motor by demand or @ end-switch
switch(state){
case STP_SLEEP:
return;
break;
case STP_MOVE0:
case STP_MOVE1:
state = STP_SLEEP;
break;
default:
state = STP_STOP;
}
}
void timer_isr(){
static uint16_t ustep = 0;
uint16_t tmp, arrval;
if(USTEPS == ++ustep){ // prevent stop @ not full step
ustep = 0;
if(state == STP_STOPZERO)
mot_position = 0;
else{
if(0 == --steps_left) state = STP_STOP;
mot_position += dir;
}
}else return;
switch(state){
case STP_ACCEL: // acceleration phase
arrval = (uint16_t)TIMx->ARR - stpsteparr;
tmp = stplowarr;
if(arrval <= tmp || arrval > stphigharr){
arrval = tmp;
state = STP_MOVE; // end of acceleration phase
}
TIMx->ARR = arrval;
break;
case STP_DECEL: // deceleration phase
arrval = (uint16_t)TIMx->ARR + stpsteparr;
tmp = stphigharr;
if(arrval >= tmp || arrval < stplowarr){
arrval = tmp;
state = STP_MVSLOW; // end of deceleration phase, move @ lowest speed
}
TIMx->ARR = arrval;
break;
case STP_MOVE: // moving with constant speed phases
if(steps_left <= ACCDECSTEPS){
state = STP_DECEL; // change moving status to decelerate
}
break;
case STP_MVSLOW:
// nothing to do here: all done before switch()
break;
default: // STP_STOP, STP_STOPZERO
ustep = 0;
TIMx->CCMR1 = TIM_CCMR1_OC1M_2; // Force inactive
TIMx->CR1 &= ~TIM_CR1_CEN; // stop timer
DRV_DISABLE();
dir = 0;
steps_left = 0;
state = STP_SLEEP;
break;
}
TIMx->SR = 0;
}

View File

@ -21,16 +21,61 @@
#include <stm32f0.h>
// the lowest speed equal to [max speed] / LOWEST_SPEED_DIV
#define LOWEST_SPEED_DIV 30
// min/max value of ACCDECSTEPS
#define ACCDECSTEPS_MIN 30
#define ACCDECSTEPS_MAX 2000
typedef enum{
DRV_NONE, // driver is absent
DRV_NOTINIT,// not initialized
DRV_MAILF, // mailfunction - no Vdd when Vio_ON activated
DRV_8825, // DRV8825 connected
DRV_4988, // A4988 connected
DRV_2130 // TMC2130 connected
DRV_2130, // TMC2130 connected
DRV_MAX // amount of records in enum
} drv_type;
// stepper states
typedef enum{
STP_SLEEP, // don't moving
STP_ACCEL, // start moving with acceleration
STP_MOVE, // moving with constant speed
STP_MVSLOW, // moving with slowest constant speed
STP_DECEL, // moving with deceleration
STP_STOP, // stop motor right now (by demand)
STP_STOPZERO, // stop motor and zero its position (on end-switch)
STP_MOVE0, // move towards 0 endswitch (negative direction)
STP_MOVE1, // move towards 1 endswitch (positive direction)
} stp_state;
typedef enum{
STPS_ALLOK, // no errors
STPS_ACTIVE, // motor is still moving
STPS_TOOBIG, // amount of steps too big
STPS_ZEROMOVE, // give 0 steps to move
STPS_ONESW // staying on end-switch & try to move further
} stp_status;
extern int32_t mot_position;
extern uint32_t steps_left;
extern stp_state state;
#define stp_getstate() (state)
drv_type initDriver();
drv_type getDrvType();
uint16_t getMaxUsteps();
void stp_chspd();
stp_status stp_move(int32_t steps);
void stp_stop();
void stp_process();
void stp_chARR(uint32_t val);
#endif // STEPPERS_H__

View File

@ -165,7 +165,7 @@ void CAN_setup(uint16_t speed){
CAN->MCR &=~ CAN_MCR_SLEEP; /* (3) */
CAN->MCR |= CAN_MCR_ABOM; /* allow automatically bus-off */
CAN->BTR |= 2 << 20 | 3 << 16 | (6000/speed) << 0; /* (4) */
CAN->BTR |= 2 << 20 | 3 << 16 | (6000/speed - 1); /* (4) */
CAN->MCR &=~ CAN_MCR_INRQ; /* (5) */
tmout = 16000000;
while((CAN->MSR & CAN_MSR_INAK)==CAN_MSR_INAK) if(--tmout == 0) break; /* (6) */

View File

@ -544,8 +544,13 @@ void printu(uint32_t val){
void printuhex(uint32_t val){
addtobuf("0x");
uint8_t *ptr = (uint8_t*)&val + 3;
int8_t i, j;
int8_t i, j, z=1;
for(i = 0; i < 4; ++i, --ptr){
if(*ptr == 0){ // omit leading zeros
if(i == 3) z = 0;
if(z) continue;
}
else z = 0;
for(j = 1; j > -1; --j){
uint8_t half = (*ptr >> (4*j)) & 0x0f;
if(half < 10) bufputchar(half + '0');

Binary file not shown.