mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 10:45:11 +03:00
add flash.c and all stubs for common functions
This commit is contained in:
parent
2ecd2d188e
commit
617daf62c7
@ -142,7 +142,7 @@ void CAN_setup(uint16_t speed){
|
|||||||
CAN->BTR = 2 << 20 | 3 << 16 | (4500/speed - 1); //| CAN_BTR_SILM | CAN_BTR_LBKM; /* (4) */
|
CAN->BTR = 2 << 20 | 3 << 16 | (4500/speed - 1); //| CAN_BTR_SILM | CAN_BTR_LBKM; /* (4) */
|
||||||
CAN->MCR &= ~CAN_MCR_INRQ; /* (5) */
|
CAN->MCR &= ~CAN_MCR_INRQ; /* (5) */
|
||||||
tmout = 10000;
|
tmout = 10000;
|
||||||
while((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) /* (6) */
|
while(CAN->MSR & CAN_MSR_INAK) /* (6) */
|
||||||
if(--tmout == 0) break;
|
if(--tmout == 0) break;
|
||||||
if(tmout==0){ DBG("timeout!\n");}
|
if(tmout==0){ DBG("timeout!\n");}
|
||||||
// accept ALL
|
// accept ALL
|
||||||
@ -355,6 +355,8 @@ static void can_process_fifo(uint8_t fifo_num){
|
|||||||
*RFxR = 0; // clear FOVR & FULL
|
*RFxR = 0; // clear FOVR & FULL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
void usb_lp_can1_rx0_isr(){ // Rx FIFO0 (overrun)
|
void usb_lp_can1_rx0_isr(){ // Rx FIFO0 (overrun)
|
||||||
if(CAN->RF0R & CAN_RF0R_FOVR0){ // FIFO overrun
|
if(CAN->RF0R & CAN_RF0R_FOVR0){ // FIFO overrun
|
||||||
CAN->RF0R &= ~CAN_RF0R_FOVR0;
|
CAN->RF0R &= ~CAN_RF0R_FOVR0;
|
||||||
|
|||||||
155
F3:F303/Multistepper/commonproto.c
Normal file
155
F3:F303/Multistepper/commonproto.c
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
* 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 "commonproto.h"
|
||||||
|
#include "hdr.h"
|
||||||
|
#include "proto.h"
|
||||||
|
#include "usb.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define NOPARCHK(par) do{if(PARBASE(par) != CANMESG_NOPAR) 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; }
|
||||||
|
|
||||||
|
errcodes cu_ping(_U_ uint8_t par, _U_ int32_t *val){
|
||||||
|
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;
|
||||||
|
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_adc(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||||
|
errcodes cu_button(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||||
|
errcodes cu_canid(_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_esw(_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_mcut(_U_ uint8_t par, _U_ int32_t *val){return ERR_BADCMD;}
|
||||||
|
errcodes cu_mcuvdd(_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;}
|
||||||
|
|
||||||
|
|
||||||
|
const fpointer cmdlist[CCMD_AMOUNT] = {
|
||||||
|
// different commands
|
||||||
|
[CCMD_PING] = cu_ping,
|
||||||
|
[CCMD_RELAY] = cu_nosuchfn,
|
||||||
|
[CCMD_BUZZER] = cu_nosuchfn,
|
||||||
|
[CCMD_ADC] = cu_adc,
|
||||||
|
[CCMD_BUTTONS] = cu_button,
|
||||||
|
[CCMD_ESWSTATE] = cu_esw,
|
||||||
|
[CCMD_MCUT] = cu_mcut,
|
||||||
|
[CCMD_MCUVDD] = cu_mcuvdd,
|
||||||
|
[CCMD_RESET] = cu_reset,
|
||||||
|
[CCMD_TIMEFROMSTART] = cu_time,
|
||||||
|
[CCMD_PWM] = cu_nosuchfn,
|
||||||
|
[CCMD_EXT] = cu_gpio,
|
||||||
|
// configuration
|
||||||
|
[CCMD_SAVECONF] = cu_saveconf,
|
||||||
|
[CCMD_ENCSTEPMIN] = cu_nosuchfn,
|
||||||
|
[CCMD_ENCSTEPMAX] = cu_nosuchfn,
|
||||||
|
[CCMD_MICROSTEPS] = cu_microsteps,
|
||||||
|
[CCMD_ACCEL] = cu_accel,
|
||||||
|
[CCMD_MAXSPEED] = cu_maxspeed,
|
||||||
|
[CCMD_MINSPEED] = cu_minspeed,
|
||||||
|
[CCMD_SPEEDLIMIT] = cu_speedlimit,
|
||||||
|
[CCMD_MAXSTEPS] = cu_maxsteps,
|
||||||
|
[CCMD_ENCREV] = cu_nosuchfn,
|
||||||
|
[CCMD_MOTFLAGS] = cu_motflags,
|
||||||
|
[CCMD_ESWREACT] = cu_eswreact,
|
||||||
|
// motor's commands
|
||||||
|
[CCMD_ABSPOS] = cu_goto,
|
||||||
|
[CCMD_RELPOS] = cu_relpos,
|
||||||
|
[CCMD_RELSLOW] = cu_relslow,
|
||||||
|
[CCMD_EMERGSTOP] = cu_emstop,
|
||||||
|
[CCMD_EMERGSTOPALL] = cu_emstop, // without args
|
||||||
|
[CCMD_STOP] = cu_stop,
|
||||||
|
[CCMD_REINITMOTORS] = cu_motreinit,
|
||||||
|
[CCMD_MOTORSTATE] = cu_state,
|
||||||
|
[CCMD_ENCPOS] = cu_nosuchfn,
|
||||||
|
[CCMD_SETPOS] = cu_abspos,
|
||||||
|
[CCMD_GOTOZERO] = cu_gotoz,
|
||||||
|
// Leave all commands upper for back-compatability with 3steppers
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* cancmds[CCMD_AMOUNT] = {
|
||||||
|
[CCMD_PING] = "ping",
|
||||||
|
[CCMD_ADC] = "adc",
|
||||||
|
[CCMD_BUTTONS] = "button",
|
||||||
|
[CCMD_ESWSTATE] = "esw",
|
||||||
|
[CCMD_MCUT] = "mcut",
|
||||||
|
[CCMD_MCUVDD] = "mcuvdd",
|
||||||
|
[CCMD_RESET] = "reset",
|
||||||
|
[CCMD_TIMEFROMSTART] = "time",
|
||||||
|
[CCMD_EXT] = "gpio",
|
||||||
|
[CCMD_SAVECONF] = "saveconf",
|
||||||
|
[CCMD_MICROSTEPS] = "microsteps",
|
||||||
|
[CCMD_ACCEL] = "accel",
|
||||||
|
[CCMD_MAXSPEED] = "maxspeed",
|
||||||
|
[CCMD_MINSPEED] = "minspeed",
|
||||||
|
[CCMD_SPEEDLIMIT] = "speedlimit",
|
||||||
|
[CCMD_MAXSTEPS] = "maxsteps",
|
||||||
|
[CCMD_MOTFLAGS] = "motflags",
|
||||||
|
[CCMD_ESWREACT] = "eswreact",
|
||||||
|
[CCMD_ABSPOS] = "goto",
|
||||||
|
[CCMD_RELPOS] = "relpos",
|
||||||
|
[CCMD_RELSLOW] = "relslow",
|
||||||
|
[CCMD_EMERGSTOP] = "emstop N",
|
||||||
|
[CCMD_EMERGSTOPALL] = "emstop",
|
||||||
|
[CCMD_STOP] = "stop",
|
||||||
|
[CCMD_REINITMOTORS] = "motreinit",
|
||||||
|
[CCMD_MOTORSTATE] = "state",
|
||||||
|
[CCMD_SETPOS] = "abspos",
|
||||||
|
[CCMD_GOTOZERO] = "gotoz"
|
||||||
|
};
|
||||||
131
F3:F303/Multistepper/commonproto.h
Normal file
131
F3:F303/Multistepper/commonproto.h
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifndef _U_
|
||||||
|
#define _U_ __attribute__((unused))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// message have no parameter
|
||||||
|
#define CANMESG_NOPAR (127)
|
||||||
|
// message is setter (have value)
|
||||||
|
#define SETTERFLAG (0x80)
|
||||||
|
#define ISSETTER(x) ((x & SETTERFLAG) ? 1 : 0)
|
||||||
|
// base value of parameter (even if it is a setter)
|
||||||
|
#define PARBASE(x) (x & 0x7f)
|
||||||
|
|
||||||
|
// error codes for answer message
|
||||||
|
typedef enum{
|
||||||
|
ERR_OK, // 0 - all OK
|
||||||
|
ERR_BADPAR, // 1 - parameter's value is wrong
|
||||||
|
ERR_BADVAL, // 2 - wrong parameter's value
|
||||||
|
ERR_WRONGLEN, // 3 - wrong message length
|
||||||
|
ERR_BADCMD, // 4 - unknown command
|
||||||
|
ERR_CANTRUN, // 5 - can't run given command due to bad parameters or other
|
||||||
|
ERR_AMOUNT // amount of error codes
|
||||||
|
} errcodes;
|
||||||
|
|
||||||
|
// pointer to function for command execution, both should be non-NULL for common cases
|
||||||
|
// if(par &0x80) it is setter, if not - getter
|
||||||
|
// if par == 0x127 it means absense of parameter!!!
|
||||||
|
// @return CANERR_OK (0) if OK or error code
|
||||||
|
typedef errcodes (*fpointer)(uint8_t par, int32_t *val);
|
||||||
|
|
||||||
|
enum{
|
||||||
|
CCMD_NONE // omit zero
|
||||||
|
,CCMD_PING // ping device
|
||||||
|
,CCMD_RELAY // relay on/off
|
||||||
|
,CCMD_BUZZER // buzzer on/off
|
||||||
|
,CCMD_ADC // ADC ch#
|
||||||
|
,CCMD_BUTTONS // buttons
|
||||||
|
,CCMD_ESWSTATE // end-switches state
|
||||||
|
,CCMD_MCUT // MCU temperature
|
||||||
|
,CCMD_MCUVDD // MCU Vdd
|
||||||
|
,CCMD_RESET // software reset
|
||||||
|
,CCMD_TIMEFROMSTART // get time from start
|
||||||
|
,CCMD_PWM // PWM value
|
||||||
|
,CCMD_EXT // value on EXTx outputs
|
||||||
|
,CCMD_SAVECONF // save configuration
|
||||||
|
,CCMD_ENCSTEPMIN // min ticks of encoder per one step
|
||||||
|
,CCMD_ENCSTEPMAX // max ticks of encoder per one step
|
||||||
|
,CCMD_MICROSTEPS // get/set microsteps
|
||||||
|
,CCMD_ACCEL // set/get acceleration/deceleration
|
||||||
|
,CCMD_MAXSPEED // set/get maximal speed
|
||||||
|
,CCMD_MINSPEED // set/get minimal speed
|
||||||
|
,CCMD_SPEEDLIMIT // get limit of speed for current microsteps settings
|
||||||
|
,CCMD_MAXSTEPS // max steps (-max..+max)
|
||||||
|
,CCMD_ENCREV // encoder's pulses per revolution
|
||||||
|
,CCMD_MOTFLAGS // motor flags
|
||||||
|
,CCMD_ESWREACT // ESW reaction flags
|
||||||
|
,CCMD_REINITMOTORS // re-init motors after configuration changing
|
||||||
|
,CCMD_ABSPOS // current position (set/get)
|
||||||
|
,CCMD_RELPOS // set relative steps or get steps left
|
||||||
|
,CCMD_RELSLOW // change relative position at lowest speed
|
||||||
|
,CCMD_EMERGSTOP // stop moving NOW
|
||||||
|
,CCMD_STOP // smooth motor stop
|
||||||
|
,CCMD_EMERGSTOPALL // emergency stop for all motors
|
||||||
|
,CCMD_GOTOZERO // go to zero's ESW
|
||||||
|
,CCMD_MOTORSTATE // motor state
|
||||||
|
,CCMD_ENCPOS // position of encoder (independing on settings)
|
||||||
|
,CCMD_SETPOS // set motor position
|
||||||
|
// should be the last:
|
||||||
|
,CCMD_AMOUNT // amount of common commands
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
// 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);
|
||||||
246
F3:F303/Multistepper/flash.c
Normal file
246
F3:F303/Multistepper/flash.c
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stm32f3.h>
|
||||||
|
#include <string.h> // memcpy
|
||||||
|
#include "flash.h"
|
||||||
|
#include "hdr.h"
|
||||||
|
#include "proto.h"
|
||||||
|
#include "steppers.h"
|
||||||
|
#include "strfunc.h"
|
||||||
|
#include "usb.h"
|
||||||
|
|
||||||
|
extern const uint32_t __varsstart, _BLOCKSIZE;
|
||||||
|
|
||||||
|
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 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} \
|
||||||
|
}
|
||||||
|
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'
|
||||||
|
const user_conf *Flash_Data = (const user_conf *)(&__varsstart);
|
||||||
|
|
||||||
|
user_conf the_conf = USERCONF_INITIALIZER;
|
||||||
|
|
||||||
|
static int currentconfidx = -1; // index of current configuration
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief binarySearch - binary search in flash for last non-empty cell
|
||||||
|
* any struct searched should have its sizeof() @ the first field!!!
|
||||||
|
* @param l - left index
|
||||||
|
* @param r - right index (should be @1 less than last index!)
|
||||||
|
* @param start - starting address
|
||||||
|
* @param stor_size - size of structure to search
|
||||||
|
* @return index of non-empty cell or -1
|
||||||
|
*/
|
||||||
|
static int binarySearch(int r, const uint8_t *start, int stor_size){
|
||||||
|
int l = 0;
|
||||||
|
while(r >= l){
|
||||||
|
int mid = l + (r - l) / 2;
|
||||||
|
const uint8_t *s = start + mid * stor_size;
|
||||||
|
if(*((const uint16_t*)s) == stor_size){
|
||||||
|
if(*((const uint16_t*)(s + stor_size)) == 0xffff){ // next is free
|
||||||
|
return mid;
|
||||||
|
}else{ // element is to the right
|
||||||
|
l = mid + 1;
|
||||||
|
}
|
||||||
|
}else{ // element is to the left
|
||||||
|
r = mid - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1; // not found
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief flashstorage_init - initialization of user conf storage
|
||||||
|
* run in once @ start
|
||||||
|
*/
|
||||||
|
void flashstorage_init(){
|
||||||
|
if(FLASH_SIZE > 0 && FLASH_SIZE < 20000){
|
||||||
|
uint32_t flsz = FLASH_SIZE * FLASH_blocksize; // size in bytes
|
||||||
|
flsz -= (uint32_t)(&__varsstart) - FLASH_BASE;
|
||||||
|
maxCnum = flsz / sizeof(user_conf);
|
||||||
|
}
|
||||||
|
// -1 if there's no data at all & flash is clear; maxnum-1 if flash is full
|
||||||
|
currentconfidx = binarySearch((int)maxCnum-2, (const uint8_t*)Flash_Data, sizeof(user_conf));
|
||||||
|
if(currentconfidx > -1){
|
||||||
|
memcpy(&the_conf, &Flash_Data[currentconfidx], sizeof(user_conf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// store new configuration
|
||||||
|
// @return 0 if all OK
|
||||||
|
int store_userconf(){
|
||||||
|
// maxnum - 3 means that there always should be at least one empty record after last data
|
||||||
|
// 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;
|
||||||
|
}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));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int write2flash(const void *start, const void *wrdata, uint32_t stor_size){
|
||||||
|
int ret = 0;
|
||||||
|
if (FLASH->CR & FLASH_CR_LOCK){ // unloch flash
|
||||||
|
FLASH->KEYR = FLASH_KEY1;
|
||||||
|
FLASH->KEYR = FLASH_KEY2;
|
||||||
|
}
|
||||||
|
while (FLASH->SR & FLASH_SR_BSY);
|
||||||
|
if(FLASH->SR & FLASH_SR_WRPERR){
|
||||||
|
return 1; // write protection
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
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);
|
||||||
|
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
|
||||||
|
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){
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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)*/
|
||||||
|
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) */
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int erase_storage(){
|
||||||
|
return erase_flash(Flash_Data, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int fn_dumpconf(_U_ uint32_t hash, _U_ char *args){ // "dumpconf" (3271513185)
|
||||||
|
#ifdef EBUG
|
||||||
|
USB_sendstr("flashsize="); printu(FLASH_SIZE); USB_putbyte('*');
|
||||||
|
printu(FLASH_blocksize); USB_putbyte('='); printu(FLASH_SIZE*FLASH_blocksize);
|
||||||
|
newline();
|
||||||
|
#endif
|
||||||
|
USB_sendstr("userconf_addr="); printuhex((uint32_t)Flash_Data);
|
||||||
|
USB_sendstr("\nuserconf_idx="); printi(currentconfidx);
|
||||||
|
USB_sendstr("\nuserconf_sz="); printu(the_conf.userconf_sz);
|
||||||
|
USB_sendstr("\ncanspeed="); printu(the_conf.CANspeed);
|
||||||
|
USB_sendstr("\ncanid="); printu(the_conf.CANID);
|
||||||
|
// motors' data
|
||||||
|
for(int i = 0; i < MOTORSNO; ++i){
|
||||||
|
char cur = '0' + i;
|
||||||
|
#define PROPNAME(nm) do{newline(); USB_sendstr(nm); USB_putbyte(cur); USB_putbyte('=');}while(0)
|
||||||
|
PROPNAME("microsteps");
|
||||||
|
printu(the_conf.microsteps[i]);
|
||||||
|
PROPNAME("accel");
|
||||||
|
printu(the_conf.accel[i]);
|
||||||
|
PROPNAME("maxspeed");
|
||||||
|
printu(the_conf.maxspd[i]);
|
||||||
|
PROPNAME("minspeed");
|
||||||
|
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");
|
||||||
|
printu(the_conf.ESW_reaction[i]);
|
||||||
|
#undef PROPNAME
|
||||||
|
}
|
||||||
|
newline();
|
||||||
|
return RET_GOOD;
|
||||||
|
}
|
||||||
77
F3:F303/Multistepper/flash.h
Normal file
77
F3:F303/Multistepper/flash.h
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "hardware.h"
|
||||||
|
|
||||||
|
#ifndef _U_
|
||||||
|
#define _U_ __attribute__((unused))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// limiting values
|
||||||
|
#define MICROSTEPSMAX (512)
|
||||||
|
// (STEPS per second^2)
|
||||||
|
#define ACCELMAXSTEPS (1000)
|
||||||
|
// max encoder steps per rev
|
||||||
|
#define MAXENCREV (100000)
|
||||||
|
|
||||||
|
// register with flash size (in blocks)
|
||||||
|
#ifndef FLASH_SIZE_REG
|
||||||
|
#define FLASH_SIZE_REG ((uint32_t)0x1FFFF7CC)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FLASH_SIZE *((uint16_t*)FLASH_SIZE_REG)
|
||||||
|
|
||||||
|
// 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 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)
|
||||||
|
} motflags_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* struct to save user configurations
|
||||||
|
*/
|
||||||
|
typedef struct __attribute__((packed, aligned(4))){
|
||||||
|
uint16_t userconf_sz; // "magick number"
|
||||||
|
uint16_t CANspeed; // default CAN speed
|
||||||
|
uint16_t CANID; // identifier
|
||||||
|
uint16_t microsteps[MOTORSNO]; // microsteps amount per step
|
||||||
|
uint16_t accel[MOTORSNO]; // acceleration/deceleration (steps/s^2)
|
||||||
|
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)
|
||||||
|
} user_conf;
|
||||||
|
|
||||||
|
extern user_conf the_conf; // global user config (read from FLASH to RAM)
|
||||||
|
|
||||||
|
// data from ld-file: start address of storage
|
||||||
|
|
||||||
|
void flashstorage_init();
|
||||||
|
int store_userconf();
|
||||||
|
int erase_storage();
|
||||||
|
|
||||||
@ -37,6 +37,8 @@ extern const uint32_t BTNpins[BTNSNO];
|
|||||||
// state 1 - pressed, 0 - released (pin active is zero)
|
// state 1 - pressed, 0 - released (pin active is zero)
|
||||||
#define BTN_state(x) ((BTNports[x]->IDR & BTNpins[x]) ? 0 : 1)
|
#define BTN_state(x) ((BTNports[x]->IDR & BTNpins[x]) ? 0 : 1)
|
||||||
|
|
||||||
|
// motors amount
|
||||||
|
#define MOTORSNO (8)
|
||||||
|
|
||||||
extern volatile uint32_t Tms;
|
extern volatile uint32_t Tms;
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "can.h"
|
#include "can.h"
|
||||||
|
#include "flash.h"
|
||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
#include "proto.h"
|
#include "proto.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
@ -37,11 +38,12 @@ int main(void){
|
|||||||
StartHSI();
|
StartHSI();
|
||||||
SysTick_Config((uint32_t)48000); // 1ms
|
SysTick_Config((uint32_t)48000); // 1ms
|
||||||
}
|
}
|
||||||
hw_setup();
|
flashstorage_init();
|
||||||
|
hw_setup(); // GPIO, ADC, timers, watchdog etc.
|
||||||
USBPU_OFF(); // make a reconnection
|
USBPU_OFF(); // make a reconnection
|
||||||
USB_setup();
|
USB_setup();
|
||||||
USBPU_ON();
|
USBPU_ON();
|
||||||
CAN_setup(100);
|
CAN_setup(the_conf.CANspeed);
|
||||||
uint32_t ctr = 0;
|
uint32_t ctr = 0;
|
||||||
CAN_message *can_mesg;
|
CAN_message *can_mesg;
|
||||||
while(1){
|
while(1){
|
||||||
|
|||||||
BIN
F3:F303/Multistepper/multistepper.bin
Executable file
BIN
F3:F303/Multistepper/multistepper.bin
Executable file
Binary file not shown.
@ -1,5 +1,9 @@
|
|||||||
can.c
|
can.c
|
||||||
can.h
|
can.h
|
||||||
|
commonproto.c
|
||||||
|
commonproto.h
|
||||||
|
flash.c
|
||||||
|
flash.h
|
||||||
hardware.c
|
hardware.c
|
||||||
hardware.h
|
hardware.h
|
||||||
hashgen/hashgen.c
|
hashgen/hashgen.c
|
||||||
@ -11,6 +15,7 @@ proto.c
|
|||||||
proto.h
|
proto.h
|
||||||
ringbuffer.c
|
ringbuffer.c
|
||||||
ringbuffer.h
|
ringbuffer.h
|
||||||
|
steppers.h
|
||||||
strfunc.c
|
strfunc.c
|
||||||
strfunc.h
|
strfunc.h
|
||||||
usb.c
|
usb.c
|
||||||
|
|||||||
@ -20,9 +20,11 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "can.h"
|
#include "can.h"
|
||||||
|
#include "flash.h"
|
||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
#include "hdr.h"
|
#include "hdr.h"
|
||||||
#include "proto.h"
|
#include "proto.h"
|
||||||
|
#include "commonproto.h"
|
||||||
#include "version.inc"
|
#include "version.inc"
|
||||||
|
|
||||||
// software ignore buffer size
|
// software ignore buffer size
|
||||||
@ -371,20 +373,134 @@ int fn_canresume(_U_ uint32_t hash, _U_ char *args){
|
|||||||
return RET_GOOD;
|
return RET_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fn_reset(_U_ uint32_t hash, _U_ char *args){
|
// dump base commands codes (for CAN protocol)
|
||||||
|
int fn_dumpcmd(_U_ uint32_t hash, _U_ char *args){ // "dumpcmd" (1223955823)
|
||||||
|
USB_sendstr("CANbus commands list:\n");
|
||||||
|
for(uint16_t i = 1; i < CCMD_AMOUNT; ++i){
|
||||||
|
if(!cancmds[i]) continue;
|
||||||
|
printu(i);
|
||||||
|
USB_sendstr(" - ");
|
||||||
|
USB_sendstr(cancmds[i]);
|
||||||
|
newline();
|
||||||
|
}
|
||||||
|
return RET_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fn_reset(_U_ uint32_t hash, _U_ char *args){ // "reset" (1907803304)
|
||||||
USB_sendstr("Soft reset\n");
|
USB_sendstr("Soft reset\n");
|
||||||
USB_sendall(); // wait until everything will gone
|
USB_sendall(); // wait until everything will gone
|
||||||
NVIC_SystemReset();
|
NVIC_SystemReset();
|
||||||
return RET_GOOD;
|
return RET_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fn_time(_U_ uint32_t hash, _U_ char *args){
|
int fn_time(_U_ uint32_t hash, _U_ char *args){ // "time" (19148340)
|
||||||
USB_sendstr("Time (ms): ");
|
USB_sendstr("Time (ms): ");
|
||||||
printu(Tms);
|
printu(Tms);
|
||||||
USB_putbyte('\n');
|
USB_putbyte('\n');
|
||||||
return RET_GOOD;
|
return RET_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* errtxt[ERR_AMOUNT] = {
|
||||||
|
[ERR_OK] = "all OK",
|
||||||
|
[ERR_BADPAR] = "wrong parameter's value",
|
||||||
|
[ERR_BADVAL] = "wrong setter of parameter",
|
||||||
|
[ERR_WRONGLEN] = "bad message length",
|
||||||
|
[ERR_BADCMD] = "unknown command",
|
||||||
|
[ERR_CANTRUN] = "temporary can't run given command",
|
||||||
|
};
|
||||||
|
int fn_dumperr(_U_ uint32_t hash, _U_ char *args){ // "dumperr" (1223989764)
|
||||||
|
USND("Error codes:");
|
||||||
|
for(int i = 0; i < ERR_AMOUNT; ++i){
|
||||||
|
printu(i); USB_sendstr(" - ");
|
||||||
|
USB_sendstr(errtxt[i]); newline();
|
||||||
|
}
|
||||||
|
return RET_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int canusb_function(uint32_t hash, char *args){
|
||||||
|
errcodes e = ERR_BADCMD;
|
||||||
|
uint32_t N;
|
||||||
|
int32_t val = 0;
|
||||||
|
uint8_t par = CANMESG_NOPAR;
|
||||||
|
if(*args){
|
||||||
|
const char *n = getnum(args, &N);
|
||||||
|
if(n != args){ // get parameter
|
||||||
|
if(N >= CANMESG_NOPAR){
|
||||||
|
USND("Wrong parameter value");
|
||||||
|
return RET_GOOD;
|
||||||
|
}
|
||||||
|
par = (uint8_t) N;
|
||||||
|
n = strchr(n, '=');
|
||||||
|
if(n){
|
||||||
|
const char *nxt = getnum(n, &N);
|
||||||
|
if(nxt != n){ // give flag issetter
|
||||||
|
val = (int32_t) N;
|
||||||
|
par |= SETTERFLAG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch(hash){
|
||||||
|
case CMD_PING:
|
||||||
|
e = cu_ping(par, &val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if(e < ERR_OK || e >= ERR_AMOUNT) USND("Bad return code");
|
||||||
|
//else
|
||||||
|
if(ERR_OK != e){
|
||||||
|
USB_sendstr(errtxt[e]); newline();
|
||||||
|
}else{
|
||||||
|
USB_sendstr("OK par");
|
||||||
|
if(par != CANMESG_NOPAR) printu(PARBASE(par));
|
||||||
|
USB_putbyte('='); printi(val);
|
||||||
|
newline();
|
||||||
|
}
|
||||||
|
return RET_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define AL __attribute__ ((alias ("canusb_function")))
|
||||||
|
|
||||||
|
// COMMON with CAN
|
||||||
|
int fn_ping(_U_ uint32_t hash, _U_ char *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_canid(_U_ uint32_t hash, _U_ char *args) AL; // "canid" (2040257924)
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief cmd_parser - command parsing
|
* @brief cmd_parser - command parsing
|
||||||
* @param txt - buffer with commands & data
|
* @param txt - buffer with commands & data
|
||||||
|
|||||||
@ -24,6 +24,7 @@
|
|||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
|
|
||||||
#define printu(x) do{USB_sendstr(u2str(x));}while(0)
|
#define printu(x) do{USB_sendstr(u2str(x));}while(0)
|
||||||
|
#define printi(x) do{USB_sendstr(i2str(x));}while(0)
|
||||||
#define printuhex(x) do{USB_sendstr(uhex2str(x));}while(0)
|
#define printuhex(x) do{USB_sendstr(uhex2str(x));}while(0)
|
||||||
|
|
||||||
extern uint8_t ShowMsgs; // show CAN messages flag
|
extern uint8_t ShowMsgs; // show CAN messages flag
|
||||||
|
|||||||
72
F3:F303/Multistepper/steppers.h
Normal file
72
F3:F303/Multistepper/steppers.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stm32f3.h>
|
||||||
|
#include "commonproto.h"
|
||||||
|
|
||||||
|
// amount of tries to detect motor stall
|
||||||
|
#define NSTALLEDMAX (5)
|
||||||
|
// amount of steps to detect stalled state
|
||||||
|
#define STALLEDSTEPS (15)
|
||||||
|
// amount of tries to keep current position (need for states near problem places)
|
||||||
|
#define KEEPPOSMAX (10)
|
||||||
|
|
||||||
|
// stepper states
|
||||||
|
typedef enum{
|
||||||
|
STP_RELAX, // 0 - no moving
|
||||||
|
STP_ACCEL, // 1 - start moving with acceleration
|
||||||
|
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_ERR // 6 - wrong/error state
|
||||||
|
} stp_state;
|
||||||
|
|
||||||
|
// end-switches reaction
|
||||||
|
enum{
|
||||||
|
ESW_IGNORE, // don't stop @ end-switch
|
||||||
|
ESW_ANYSTOP, // stop @ esw in any moving direction
|
||||||
|
ESW_STOPMINUS, // stop only in negative moving
|
||||||
|
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);
|
||||||
|
errcodes getremainsteps(uint8_t i, int32_t *position);
|
||||||
|
errcodes motor_absmove(uint8_t i, int32_t abssteps);
|
||||||
|
errcodes motor_relmove(uint8_t i, int32_t relsteps);
|
||||||
|
errcodes motor_relslow(uint8_t i, int32_t relsteps);
|
||||||
|
errcodes motor_goto0(uint8_t i);
|
||||||
|
|
||||||
|
uint8_t geteswreact(uint8_t i);
|
||||||
|
|
||||||
|
void emstopmotor(uint8_t i);
|
||||||
|
void stopmotor(uint8_t i);
|
||||||
|
stp_state getmotstate(uint8_t i);
|
||||||
|
void process_steppers();
|
||||||
@ -1,2 +1,2 @@
|
|||||||
#define BUILD_NUMBER "11"
|
#define BUILD_NUMBER "20"
|
||||||
#define BUILD_DATE "2023-02-07"
|
#define BUILD_DATE "2023-02-13"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user