add some shit, but still have a problem
@ -10,6 +10,11 @@ DEFS += -DEBUG
|
||||
# for example, if you have STM32F103VBT6, you should write:
|
||||
LDSCRIPT ?= stm32f072B.ld
|
||||
|
||||
# autoincremental version & build date
|
||||
VERSION_FILE = version.inc
|
||||
NEXTVER := $(shell expr $$(awk '/#define BUILD_NUMBER/' $(VERSION_FILE) | tr -cd "[0-9]") + 1)
|
||||
BUILDDATE := $(shell date +%Y-%m-%d)
|
||||
|
||||
INDEPENDENT_HEADERS=
|
||||
|
||||
FP_FLAGS ?= -msoft-float
|
||||
@ -100,7 +105,15 @@ $(OBJDIR):
|
||||
$(STARTUP): $(INC_DIR)/startup/vector.c
|
||||
$(CC) $(CFLAGS) $(DEFS) $(INCLUDE) $(ARCH_FLAGS) -o $@ -c $<
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
$(VERSION_FILE): *.[ch]
|
||||
@echo "Generate version: $(NEXTVER) for date $(BUILDDATE)"
|
||||
@sed -i "s/#define BUILD_NUMBER.*/#define BUILD_NUMBER \"$(NEXTVER)\"/" $(VERSION_FILE)
|
||||
@sed -i "s/#define BUILD_DATE.*/#define BUILD_DATE \"$(BUILDDATE)\"/" $(VERSION_FILE)
|
||||
|
||||
$(OBJDIR)/strfunct.o: strfunct.c $(VERSION_FILE)
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
@make $(VERSION_FILE)
|
||||
@echo " CC $<"
|
||||
$(CC) $(CFLAGS) $(DEFS) $(INCLUDE) $(ARCH_FLAGS) -o $@ -c $<
|
||||
|
||||
@ -108,10 +121,7 @@ $(OBJDIR)/%.o: %.c
|
||||
@echo " ASM $<"
|
||||
$(CC) $(CFLAGS) $(DEFS) $(INCLUDE) $(ARCH_FLAGS) -S -o $(OBJDIR)/$@ -c $<
|
||||
|
||||
#$(OBJDIR)/%.d: %.c $(OBJDIR)
|
||||
# $(CC) -MM -MG $< | sed -e 's,^\([^:]*\)\.o[ ]*:,$(@D)/\1.o $(@D)/\1.d:,' >$@
|
||||
|
||||
$(BIN): $(ELF)
|
||||
$(BIN): $(ELF)
|
||||
@echo " OBJCOPY $(BIN)"
|
||||
$(OBJCOPY) -Obinary $(ELF) $(BIN)
|
||||
|
||||
|
||||
@ -117,7 +117,6 @@ void CAN_setup(uint16_t speed){
|
||||
// Configure CAN
|
||||
CAN->MCR |= CAN_MCR_INRQ; // Enter CAN init mode to write the configuration
|
||||
while((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK){
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
if(--tmout == 0) break;
|
||||
}
|
||||
CAN->MCR &=~ CAN_MCR_SLEEP;
|
||||
@ -126,7 +125,6 @@ void CAN_setup(uint16_t speed){
|
||||
CAN->MCR &=~ CAN_MCR_INRQ;
|
||||
tmout = 16000000;
|
||||
while((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK){ // Wait the init mode leaving
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
if(--tmout == 0) break;
|
||||
}
|
||||
// accept self ID at filter 0, ALL other at filters 1 and 2
|
||||
@ -163,7 +161,6 @@ void can_proc(){
|
||||
if(CAN->RF1R & CAN_RF1R_FMP1){
|
||||
can_process_fifo(1);
|
||||
}
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
if(CAN->ESR & (CAN_ESR_BOFF | CAN_ESR_EPVF | CAN_ESR_EWGF)){ // much errors - restart CAN BUS
|
||||
SEND("\nToo much errors, restarting CAN!\n");
|
||||
SEND("Receive error counter: ");
|
||||
@ -187,7 +184,6 @@ void can_proc(){
|
||||
if(CAN->ESR & CAN_ESR_EPVF) SEND("Passive error limit");
|
||||
if(CAN->ESR & CAN_ESR_EWGF) SEND("Error counter limit");
|
||||
NL();
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
// request abort for all mailboxes
|
||||
CAN->TSR |= CAN_TSR_ABRQ0 | CAN_TSR_ABRQ1 | CAN_TSR_ABRQ2;
|
||||
// reset CAN bus
|
||||
|
||||
@ -44,9 +44,9 @@ static uint32_t maxCnum = 1024 / sizeof(user_conf); // can't use blocksize here
|
||||
,.accel = {160, 160, 160} \
|
||||
,.maxspd = {1000, 1000, 1000} \
|
||||
,.maxsteps = {50000, 50000, 50000} \
|
||||
,.encrev = {800,800,800} \
|
||||
,.encperstepmin = {3,3,3} \
|
||||
,.encperstepmax = {5,5,5} \
|
||||
,.encrev = {4000,4000,4000} \
|
||||
,.encperstepmin = {16,16,16} \
|
||||
,.encperstepmax = {24,24,24} \
|
||||
,.motflags = {DEFMF,DEFMF,DEFMF} \
|
||||
,.ESW_reaction = {ESW_ANYSTOP, ESW_ANYSTOP, ESW_ANYSTOP} \
|
||||
}
|
||||
@ -220,12 +220,22 @@ void dump_userconf(_U_ char *txt){
|
||||
bufputchar('0' + the_conf.motflags[i].reverse);
|
||||
PROPNAME("microsteps");
|
||||
printu(the_conf.microsteps[i]);
|
||||
PROPNAME("accdecsteps");
|
||||
PROPNAME("accel");
|
||||
printu(the_conf.accel[i]);
|
||||
PROPNAME("maxspeed");
|
||||
printu(the_conf.maxspd[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");
|
||||
printu(the_conf.ESW_reaction[i]);
|
||||
#undef PROPNAME
|
||||
}
|
||||
NL();
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
#include "hardware.h"
|
||||
#include "can.h"
|
||||
#include "steppers.h"
|
||||
#include "strfunct.h"
|
||||
|
||||
// Buttons: PA10, PA13, PA14, PA15, pullup (0 active)
|
||||
volatile GPIO_TypeDef *BTNports[BTNSNO] = {GPIOA, GPIOA, GPIOA, GPIOA};
|
||||
@ -36,9 +37,9 @@ volatile GPIO_TypeDef *DIRports[MOTORSNO] = {GPIOB, GPIOB, GPIOB};
|
||||
const uint32_t DIRpins[MOTORSNO] = {1<<1, 1<<10, 1<<12};
|
||||
|
||||
// timers for motors
|
||||
TIM_TypeDef *mottimers[MOTORSNO] = {TIM15, TIM14, TIM16};
|
||||
volatile TIM_TypeDef *mottimers[MOTORSNO] = {TIM15, TIM14, TIM16};
|
||||
// timers for encoders
|
||||
TIM_TypeDef *enctimers[MOTORSNO] = {TIM1, TIM2, TIM3};
|
||||
volatile TIM_TypeDef *enctimers[MOTORSNO] = {TIM1, TIM2, TIM3};
|
||||
|
||||
void gpio_setup(void){
|
||||
RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOCEN | RCC_AHBENR_GPIOFEN;
|
||||
@ -84,7 +85,7 @@ void iwdg_setup(){
|
||||
static IRQn_Type motirqs[MOTORSNO] = {TIM15_IRQn, TIM14_IRQn, TIM16_IRQn};
|
||||
// motor's PWM
|
||||
static void setup_mpwm(int i){
|
||||
TIM_TypeDef *TIM = mottimers[i];
|
||||
volatile TIM_TypeDef *TIM = mottimers[i];
|
||||
TIM->CR1 = 0;
|
||||
TIM->PSC = MOTORTIM_PSC - 1; // 64kHz
|
||||
// PWM mode 1 (OCxM = 110), preload enable
|
||||
@ -92,16 +93,15 @@ static void setup_mpwm(int i){
|
||||
TIM->CCER = TIM_CCER_CC1E; // turn it on, active high
|
||||
TIM->CCR1 = 1; // 20.8us for pulse duration, according to datasheet 1.9us is enough
|
||||
TIM->BDTR |= TIM_BDTR_MOE; // enable main output
|
||||
// TIM->CR1 |= TIM_CR1_CEN; // enable timer
|
||||
TIM->EGR |= TIM_EGR_UG; // force update generation
|
||||
TIM->DIER = TIM_DIER_CC1IE; // allow CC interrupt (we should count steps)
|
||||
TIM->CNT = 0;
|
||||
NVIC_EnableIRQ(motirqs[i]);
|
||||
}
|
||||
|
||||
static IRQn_Type encirqs[MOTORSNO] = {TIM1_BRK_UP_TRG_COM_IRQn, TIM2_IRQn, TIM3_IRQn};
|
||||
static void setup_enc(int i){
|
||||
TIM_TypeDef *TIM = enctimers[i];
|
||||
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
|
||||
volatile TIM_TypeDef *TIM = enctimers[i];
|
||||
/* (1) Configure TI1FP1 on TI1 (CC1S = 01)
|
||||
configure TI1FP2 on TI2 (CC2S = 01)
|
||||
filters sampling = fDTS/8, N=6 */
|
||||
@ -119,6 +119,7 @@ static void setup_enc(int i){
|
||||
TIM->ARR = the_conf.encrev[i];
|
||||
// enable timer
|
||||
TIM->CR1 = TIM_CR1_CKD_1 | TIM_CR1_CEN; /* (4) */
|
||||
TIM->CNT = 0;
|
||||
NVIC_EnableIRQ(encirqs[i]);
|
||||
}
|
||||
|
||||
@ -189,17 +190,26 @@ uint8_t MSB(uint16_t val){
|
||||
}
|
||||
|
||||
void tim14_isr(){
|
||||
addmicrostep(0);
|
||||
TIM14->SR = 0;
|
||||
TIM14->CR1 &= TIM_CR1_CEN;
|
||||
DBG("UP1");
|
||||
//addmicrostep(1);
|
||||
}
|
||||
void tim15_isr(){
|
||||
addmicrostep(1);
|
||||
TIM15->SR = 0;
|
||||
TIM15->CR1 &= TIM_CR1_CEN;
|
||||
DBG("UP0");
|
||||
//addmicrostep(0);
|
||||
}
|
||||
void tim16_isr(){
|
||||
addmicrostep(2);
|
||||
TIM16->SR = 0;
|
||||
TIM16->CR1 &= TIM_CR1_CEN;
|
||||
DBG("UP2");
|
||||
//addmicrostep(2);
|
||||
}
|
||||
|
||||
|
||||
void tim1_isr(){
|
||||
void tim1_brk_up_trg_com_isr(){
|
||||
encoders_UPD(0);
|
||||
}
|
||||
void tim2_isr(){
|
||||
|
||||
@ -191,9 +191,9 @@ extern const uint32_t DIRpins[MOTORSNO];
|
||||
extern volatile uint32_t Tms;
|
||||
|
||||
// timers of motors
|
||||
extern TIM_TypeDef *mottimers[];
|
||||
extern volatile TIM_TypeDef *mottimers[];
|
||||
// timers for encoders
|
||||
extern TIM_TypeDef *enctimers[];
|
||||
extern volatile TIM_TypeDef *enctimers[];
|
||||
|
||||
void gpio_setup();
|
||||
void iwdg_setup();
|
||||
|
||||
@ -70,6 +70,7 @@ static char *get_USB(){
|
||||
int main(void){
|
||||
uint8_t ctr, len;
|
||||
CAN_message *can_mesg;
|
||||
//uint32_t oS = 0;
|
||||
char *txt;
|
||||
sysreset();
|
||||
SysTick_Config(6000, 1);
|
||||
@ -84,8 +85,13 @@ int main(void){
|
||||
|
||||
while (1){
|
||||
IWDG->KR = IWDG_REFRESH; // refresh watchdog
|
||||
/* if(Tms - oS > 1999){
|
||||
oS = Tms;
|
||||
SEND("2s"); NL();
|
||||
}*/
|
||||
process_keys();
|
||||
custom_buttons_process();
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
can_proc();
|
||||
if(CAN_get_status() == CAN_FIFO_OVERRUN){
|
||||
SEND("CAN bus fifo overrun occured!\n");
|
||||
|
||||
BIN
F0-nolib/3steppersLB/stepper_driver/01.jpg
Normal file
|
After Width: | Height: | Size: 101 KiB |
BIN
F0-nolib/3steppersLB/stepper_driver/02.jpg
Normal file
|
After Width: | Height: | Size: 152 KiB |
BIN
F0-nolib/3steppersLB/stepper_driver/03.jpg
Normal file
|
After Width: | Height: | Size: 111 KiB |
BIN
F0-nolib/3steppersLB/stepper_driver/04.jpg
Normal file
|
After Width: | Height: | Size: 129 KiB |
BIN
F0-nolib/3steppersLB/stepper_driver/05.jpg
Normal file
|
After Width: | Height: | Size: 76 KiB |
BIN
F0-nolib/3steppersLB/stepper_driver/06.jpg
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
F0-nolib/3steppersLB/stepper_driver/07.jpg
Normal file
|
After Width: | Height: | Size: 88 KiB |
BIN
F0-nolib/3steppersLB/stepper_driver/08.jpg
Normal file
|
After Width: | Height: | Size: 87 KiB |
BIN
F0-nolib/3steppersLB/stepper_driver/09.jpg
Normal file
|
After Width: | Height: | Size: 97 KiB |
BIN
F0-nolib/3steppersLB/stepper_driver/10.jpg
Normal file
|
After Width: | Height: | Size: 62 KiB |
@ -19,6 +19,7 @@
|
||||
#include "flash.h"
|
||||
#include "hardware.h"
|
||||
#include "steppers.h"
|
||||
#include "strfunct.h"
|
||||
|
||||
// goto zero stages
|
||||
typedef enum{
|
||||
@ -95,9 +96,9 @@ void init_steppers(){
|
||||
|
||||
// get absolute position by encoder
|
||||
static int32_t encoder_position(uint8_t i){
|
||||
int32_t pos = encpos[i]*the_conf.encrev[i];
|
||||
if(the_conf.motflags[i].encreverse) pos -= mottimers[i]->CNT;
|
||||
else pos += mottimers[i]->CNT;
|
||||
int32_t pos = encpos[i];
|
||||
if(the_conf.motflags[i].encreverse) pos -= enctimers[i]->CNT;
|
||||
else pos += enctimers[i]->CNT;
|
||||
return pos;
|
||||
}
|
||||
|
||||
@ -121,7 +122,7 @@ errcodes motor_absmove(uint8_t i, int32_t newpos){
|
||||
if(newpos > (int32_t)the_conf.maxsteps[i] || newpos < -(int32_t)the_conf.maxsteps[i] || newpos == stppos[i])
|
||||
return ERR_BADVAL; // too big position or zero
|
||||
targstppos[i] = newpos;
|
||||
prevencpos[i] = encpos[i];
|
||||
prevencpos[i] = encoder_position(i);
|
||||
prevstppos[i] = stppos[i];
|
||||
uint8_t inv = the_conf.motflags[i].reverse;
|
||||
int32_t delta = newpos - stppos[i];
|
||||
@ -170,6 +171,7 @@ stp_state getmotstate(uint8_t i){
|
||||
void addmicrostep(uint8_t i){
|
||||
static volatile uint16_t microsteps[MOTORSNO] = {0}; // current microsteps position
|
||||
if(mottimers[i]->SR & TIM_SR_UIF){
|
||||
DBG("MOTUP");
|
||||
if(ESW_state(i)){ // ESW active
|
||||
switch(the_conf.ESW_reaction[i]){
|
||||
case ESW_ANYSTOP: // stop motor in any direction
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include "hardware.h"
|
||||
#include "strfunct.h"
|
||||
#include "usb.h"
|
||||
#include "version.inc"
|
||||
|
||||
#include <string.h> // strlen
|
||||
|
||||
@ -36,7 +37,6 @@ static char buff[BUFSZ+1], *bptr = buff;
|
||||
static uint8_t blen = 0;
|
||||
|
||||
void sendbuf(){
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
if(blen == 0) return;
|
||||
*bptr = 0;
|
||||
USB_sendstr(buff);
|
||||
@ -53,7 +53,6 @@ void bufputchar(char ch){
|
||||
}
|
||||
|
||||
void addtobuf(const char *txt){
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
while(*txt) bufputchar(*txt++);
|
||||
}
|
||||
|
||||
@ -384,6 +383,20 @@ void bootldr(_U_ char *txt){
|
||||
Jump2Boot();
|
||||
}
|
||||
|
||||
void getcounter(_U_ char *txt){
|
||||
SEND("CR1="); printu(TIM1->CR1);
|
||||
SEND("\nCR2="); printu(TIM2->CR1);
|
||||
SEND("\nCR3="); printu(TIM3->CR1);
|
||||
SEND("\nCNT1="); printu(TIM1->CNT);
|
||||
SEND("\nCNT2="); printu(TIM2->CNT);
|
||||
SEND("\nCNT3="); printu(TIM3->CNT);
|
||||
NL();
|
||||
}
|
||||
|
||||
void wdcheck(_U_ char *txt){
|
||||
while(1){nop();}
|
||||
}
|
||||
|
||||
typedef void(*specfpointer)(char *arg);
|
||||
|
||||
typedef struct{
|
||||
@ -405,11 +418,14 @@ const speccommands scmdlist[] = {
|
||||
{"resume", inresume, "resume IN packets displaying"},
|
||||
{"send", sendCANcommand, "send data over CAN: send ID byte0 .. byteN"},
|
||||
{"dumpconf", dump_userconf, "dump current configuration"},
|
||||
{"getctr", getcounter, "get TIM1/2/3 counters"},
|
||||
{"wd", wdcheck, "check watchdog"},
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
static void showHelp(){
|
||||
SEND("USAGE. Common commands format is cmd[ N[ = val]]\n\twhere N is command argument (0..127), val is its value\n");
|
||||
SEND("https://github.com/eddyem/stm32samples/tree/master/F0-nolib/3steppersLB build#" BUILD_NUMBER " @ " BUILD_DATE "\n");
|
||||
SEND("Common commands format is cmd[ N[ = val]]\n\twhere N is command argument (0..127), val is its value\n");
|
||||
SEND("Common commands:\n");
|
||||
for(int i = 0; i < CMD_AMOUNT; ++i){
|
||||
bufputchar('\t'); SEND(cmdlist[i].command); SEND(" - ");
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
#define SEND(str) do{addtobuf(str);}while(0)
|
||||
|
||||
#ifdef EBUG
|
||||
#define DBG(str) do{addtobuf(__FILE__ " (L" STR(__LINE__) "): " str);}while(0)
|
||||
#define DBG(str) do{addtobuf(__FILE__ " (L" STR(__LINE__) "): " str); NL();}while(0)
|
||||
#else
|
||||
#define DBG(str)
|
||||
#endif
|
||||
|
||||
@ -71,13 +71,13 @@ void USB_setup(){
|
||||
static int usbwr(const uint8_t *buf, uint16_t l){
|
||||
uint32_t ctra = 1000000;
|
||||
while(--ctra && tx_succesfull == 0){
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
nop();
|
||||
}
|
||||
tx_succesfull = 0;
|
||||
EP_Write(3, buf, l);
|
||||
ctra = 1000000;
|
||||
while(--ctra && tx_succesfull == 0){
|
||||
IWDG->KR = IWDG_REFRESH;
|
||||
nop();
|
||||
}
|
||||
if(tx_succesfull == 0){usbON = 0; return 1;} // usb is OFF?
|
||||
return 0;
|
||||
|
||||
@ -188,7 +188,7 @@ static void wr0(const uint8_t *buf, uint16_t size){
|
||||
USB->EPnR[0] = (status & ~(USB_EPnR_CTR_RX|USB_EPnR_CTR_TX|USB_EPnR_STAT_RX))
|
||||
^ USB_EPnR_STAT_TX;
|
||||
uint32_t ctr = 1000000;
|
||||
while(--ctr && (USB->ISTR & USB_ISTR_CTR) == 0){IWDG->KR = IWDG_REFRESH;};
|
||||
while(--ctr && (USB->ISTR & USB_ISTR_CTR) == 0){nop();}
|
||||
if((USB->ISTR & USB_ISTR_CTR) == 0){
|
||||
return;
|
||||
}
|
||||
|
||||
2
F0-nolib/3steppersLB/version.inc
Normal file
@ -0,0 +1,2 @@
|
||||
#define BUILD_NUMBER "43"
|
||||
#define BUILD_DATE "2021-11-14"
|
||||