diff --git a/F3:F303/Multistepper/Makefile b/F3:F303/Multistepper/Makefile index e17542c..33e7110 100644 --- a/F3:F303/Multistepper/Makefile +++ b/F3:F303/Multistepper/Makefile @@ -4,6 +4,7 @@ MCU := F303xd # change this linking script depending on particular MCU model, LDSCRIPT := stm32f303xD.ld DEFINES := -DUSB2_16 +#DEFINES := -DUSB1_16 include ../makefile.f3 include ../../makefile.stm32 diff --git a/F3:F303/Multistepper/Readme.md b/F3:F303/Multistepper/Readme.md index d3f5790..d65409c 100644 --- a/F3:F303/Multistepper/Readme.md +++ b/F3:F303/Multistepper/Readme.md @@ -9,7 +9,7 @@ Eighth stepper could be changed to 8 dependent multiplexed. Based on STM32F303VD ### Sorted by pin number -|**Pin #**|**Pin name **| **function**| **settings** |**comment ** | +| Pin # | Pin name | function | settings | comment | |---------|-------------|-------------|---------------|---------------------| | 1 | PE2 | DIAG | in | `diag` output of TMC| | 2 | PE3 | MUL0 | slow out | multiplexer address | @@ -113,23 +113,36 @@ Eighth stepper could be changed to 8 dependent multiplexed. Based on STM32F303VD | 100 | (VDD) | | | | ### Some comments. -_DIAG_ input used to detect problems with TMC drivers (multiplexed by _MUL_ outputs). -Each motor have next control signals: _EN_ - enable driver, _DIR_ - rotation direction, _STEP_ - microstepping clock signal, _L0_ - zero end-switch, _L1_ - max end-switch (or Cable Select for SPI-based TMC). -_MOTMUL_ - external multiplexer or other GPIO signals (e.g. to manage of 64 stepper motors). -_ADC1 in_ - four external ADC signals (0..3.3V). -_SPI1_ used to manage TMC drivers in case of SPI-based. -_USART1_ - to connect external something (master or slave). -_OUT_ - external GPIO. -_USART2 Tx_ used to manage USART-based TMC (numbers 0-3). -_USART3 Tx_ used to manage USART-based TMC (numbers 4-7). -_SCRN_ - control signals for SPI TFT screen. -_BTN_ - external button, keypad, joystick etc. Two of them could be connected to I2C devices. -_USB_ and _CAN_ used as main device control buses. -_SW_ used as debugging/sewing; also (I remember about USB pullup only after end of PCB design) _SWDIO_ used as USB pullup (so the device have no USB in debug mode - when BTN0 and BTN1 are pressed at start). +**DIAG** input used to detect problems with TMC drivers (multiplexed by **MUL** outputs). + +Each motor have next control signals: **EN** - enable driver, **DIR** - rotation direction, **STEP** - microstepping clock signal, **L0** - zero end-switch, +**L1** - max end-switch (or Cable Select for SPI-based TMC). + +**MOTMUL** - external multiplexer or other GPIO signals (e.g. to manage of 64 stepper motors). + +**ADC1 in** - four external ADC signals (0..3.3V). + +**SPI1** used to manage TMC drivers in case of SPI-based. + +**USART1** - to connect external something (master or slave). + +**OUT** - external GPIO. + +**USART2 Tx** used to manage USART-based TMC (numbers 0-3). + +**USART3 Tx** used to manage USART-based TMC (numbers 4-7). + +**SCRN** - control signals for SPI TFT screen. + +**BTN** - external button, keypad, joystick etc. Two of them could be connected to I2C devices. + +**USB** and **CAN** used as main device control buses. + +**SW** used as debugging/flashing. ### Sorted by ports (with AF numbers). -|**Pin #**|**Pin name **| **function**| **settings** |**comment ** | +| Pin # | Pin name | function | settings | comment | |---------|-------------|-------------|---------------|---------------------| | 23 | PA0 | ADC1 in1 | ADC | External ADC inputs | | 24 | PA1 | ADC1 in2 | ADC | | @@ -216,18 +229,233 @@ _SW_ used as debugging/sewing; also (I remember about USB pullup only after end | 10 | PF9 | M0 STEP | AF3 (T15ch1) | clock of motor | | 11 | PF10 | M0 EN | slow out | l-s 0 or CS of SPI | - ## DMA usage * ADC1 - DMA1_ch1 * ADC2 - DMA2_ch1 -* USART2 (PDN-UART for drivers 0..3) - DMA1_ch6 (Rx), DMA1_ch7 (Tx) -* USART3 (PDN-UART for drivers 4..7) - DMA1_ch3 (Rx), DMA1_ch2 (Tx) -* SPI2 (screen) - DMA1_ch4 (Rx), DMA1_ch5 (Tx) [or may be dedicated to USART1] -# Other stepper drivers connection -## DRV8825 -Solder jumpers E2, B and A to connect ~RST and ~SLP to 3.3V. +# Stepper drivers connection -Microstepping selection produced by soldering H2 (bit0), G2 (bit1) and/or C (bit2). \ No newline at end of file +After changing stepper type by soldering/desoldering appropriate jumpers, don't forget to change their types in settings +(and save settings in MSU flash memory after checking it with `dumpconf`). + +Connection diagram for soldering jumpers shown on reverse side of PCB. + +Jumpers **A**, **B** and **C** allow to short the contacts of driver's pins 6 (CLK / DCO / ~SLEEP), 5 (PDN_UART / SDO / ~RESET) and 4 +(SPREAD / CS / M2), respectively. + +Jumper **D1** connects MCU UART output with jumper **E1**, **D2** connects MCU MISO with same contact of **E1**. +Jumpers **E1** and **E2** allows to pullup pin 5 of driver to be connected with 3.3V or UART/MISO. + +Jumper **F1** allows to connect pin 4 to CS line. **F2** connects pin 4 to 3.3V. + +Jumper **G1** connects pin 3 (MS2 / SCK / M1) to SCK line. **G2** connects this pin to 3.3V. + +Jumper **H1** connects pin pin 2 (MS1 / SDI / M0) to MOSI line **H2** connects it to 3.3V. + +So, depending on driver type and its mode you can solder these jumpers so, than driver can work over PDN-UART, SPI or configuration +pins can select microstepping directly. + + +## DRV8825 and other simplest drivers +Solder jumpers **E2**, **B** and **A** to connect **~RST** and **~SLP** to 3.3V. + +Microstepping selection produced by soldering **H2** (bit0), **G2** (bit1) and/or **C** (bit2). + +## TMC2209 and other PDN-UART based +Solder jumpers **D1** and **E1** to connect MCU UART2/UART3 to PDN-UART pin of driver. Solder jumpers **G2**/**H2** according +address table (X - soldered, O - not soldered): + +| Address | G2 | H2 | +|:-------:|:-----:|:-----:| +| 0 | **O** | **O** | +| 1 | **O** | **X** | +| 2 | **X** | **O** | +| 3 | **X** | **X** | +| 4 | **O** | **O** | +| 5 | **O** | **X** | +| 6 | **X** | **O** | +| 7 | **X** | **X** | + +## TMC2130 and other SPI based +(not negotiated yet) + +Solder jumpers **D2** and **E1** to connect MISO, **F1** to connect CS, **G1** for SCK and **H1** for MOSI. + +# Protocol + +## Errors +Error codes are in brackets: + +- **OK** (0) - all OK; +- **BADPAR** (1) - bad parameter (`N`) value (e.g. greater than max available or absent); +- **BADVAL** (2) - bad setter value (absent, text or over range); +- **WRONGLEN** (3) - (only for CAN bus, you can't meet in text protocol) wrong CAN message length; +- **BADCMD** (4) - unknown command, in case of USB proto user will see full command list instead of this error; +- **CANTRUN** (5) - can't run required function. + +## USB + +Used simple text protocol each string should contain one command and ends with `'\n'`. +Uppercase N at the end of command means parameter number (No of motor, button, ADC channel etc). +Getters and action commands have simplest format `command[N]`: some commands have no parameter, +other have two variants - with and without parameter; wariant without parameter will act on all +parameters (e.g. getter for all buttons) - in this case `N` enclosed in square brackets. +Setters have format `command[N] = value`. The `value` is integer number, so in case floating values +you need to multiply it by 1000 and write result. So, voltage and temperature are measured in millivolts +and thousandths of degC respectively. + +Some commands (especially that have no CAN analogue) have non-standard format described later. +They are not intended to be used in automatic control systems, only in manual mode. + +Answer for every (excluding special) setter and getter in case of success is `command[N]=value` +showing current value for getter or new value for setter. +In case of error you will see one of error mesages (message `OK` with errcode=0 usually not shown). +Also you can get such answers: + +- `BADCMD` - wrong command (not in dictionary); +- `BADARGS` - bad arguments format (e.g. for command `cansend` etc); +- `FAIL` - if something wrong and parser got impermissible error code. + +In following list letter `G` means "getter", `S` - "setter", no of them - custom USB-only command. +The number in brackets is CAN command code. The asterisk following command means that it isn't implemented yet (and maybe +will be never implemented). + +### absposN (35) GS +Absolute stepper position in steps, setter just changes current value. E.g. you want to set current position +as zero (be carefull: `gotoz` will zero position again on a zero-point limit switch). Maximum absolute value is `maxstepsN`. +### accelN (17) GS +Stepper acceleration/deceleration on ramp (steps/s^2), only positive. Maximum value is `ACCELMAXSTEPS` from `flash.h`. +### adcN (4) G +ADC value (N=0..3). +### buttonN (5) G +Given (N=0..6) buttons' state. If number is right, returns two strings: `buttonN=state` (where `state` is +`none`, `press`, `hold` or `release`) and `buttontmN=time` (where `time` is time from start of last event). + +!!!NOTE: Button numbering starts from 0, not 1 as shown on PCB!!! +### canerrcodes +Print last CAN errcodes. +Print "No errors" or last error code. +### canfilter DATA +CAN bus hardware filters, format: bank# FIFO# mode(M/I) num0 [num1 [num2 [num3]]] . +By default have two filters allowing to listen any CAN ID: + + Filter 0, FIFO0 in MASK mode: ID=0x01, MASK=0x01 + Filter 1, FIFO1 in MASK mode: ID=0x00, MASK=0x01 + +### canflood ID DATA +Send or clear (if empty) flood message: ID byte0 ... byteN. +On empy message return `NO ID given, send nothing!` (and stops flooding), or `Message parsed OK`. +### canfloodT N +Flood period, N in milliseconds (N >= 0ms). +### canid [ID] +Get or set CAN ID of device. Default CAN ID is "1". +### canignore [ID] +Software ignore list (max 10 IDs), negative to delete all, non-negative to add next. +### canincrflood ID +Send incremental flood message with given ID. Message have uint32_t little endian type and increments +for each packet starting from 0. Empty command stops flooding (`canflood` too). +### canpause +Pause filtered IN packets displaying. Returns `Pause CAN messages`. +### canreinit +Reinit CAN with last settings. Returns `OK`. +### canresume +Resume filtered IN packets displaying, returns `RESUME CAN messages`. +### cansend ID [data] +Send data over CAN with given ID. If `data` is omitted, send empty message. +In case of absence of `ACK` you can get message `CAN bus is off, try to restart it`. +### canspeed N +CAN bus speed (in kbps, 50 <= N <= 1500) +In case of setter, store new speed value in global parameters (and if you call `saveconf` later, it will be saved in flash memory). +### canstat +Get CAN bus status: values of registers `CAN->MSR`, `CAN->TSR`, `CAN->RF0R` and `CAN->RF1F`. +### diagn[N] (37) G * +DIAG state of motor N (or all)\n" +### drvtypeN (45) GS +Nth driver type (0 - only step/dir, 1 - UART, 2 - SPI, 3 - reserved). This parameter is taken from `.drvtype` bits of `motflags` settings parameter. +### dumperr +Dump error codes. Returns: + + Error codes: + 0 - OK + 1 - BADPAR + 2 - BADVAL + 3 - WRONGLEN + 4 - BADCMD + 5 - CANTRUN + +### dumpcmd +Dump command codes. Returns all list of CAN bus command codes. +### dumpconf +Dump current configuration. Returns a lot of information both common (like CAN bus speed, ID and so on) and +for each motor driver. You can call independeng getters for each of this parameter. +### dumpmotflags +Dump motor flags' bits (for `motflagsN`) and reaction to limit switches (`eswreact`) values: + + Motor flags: + bit0 - 0: reverse - invert motor's rotation + bit1 - 1: [reserved] + bit2 - 2: [reserved] + bit3 - 3: donthold - clear motor's power after stop + bit4 - 4: eswinv - inverse end-switches (1->0 instead of 0->1) + bit5 - 5: [reserved] + bit6 - 6,7: drvtype - driver type (0 - only step/dir, 1 - UART, 2 - SPI, 3 - reserved) + End-switches reaction: + 0 - ignore end-switches + 1 - stop @ esw in any moving direction + 2 - stop only when moving in given direction (e.g. to minus @ESW0) + +### dumpstates +Dump motors' state codes (for getter `stateN`): + + Motor's state codes: + 0 - relax + 1 - acceleration + 2 - moving + 3 - moving at lowest speed + 4 - deceleration + 5 - stalled (not used here!) + 6 - error + +### emstop[N] (29 with `N` and 31 without) +Emergency stop Nth motor or all (if `N` absent). Returns `OK` or error text. + + "eraseflash [=N] (38) erase flash data storage (full or only N'th page of it)\n" + "esw[N] (6) G end-switches state\n" + "eswreactN (24) GS end-switches reaction (0 - ignore, 1 - stop@any, 2 - stop@zero)\n" + "gotoN (26) GS move motor to given absolute position\n" + "gotozN (32) find zero position & refresh counters\n" + "gpioconfN* - GS GPIO configuration (0 - PUin, 1 - PPout, 2 - ODout), N=0..2\n" + "gpioN* (12) GS GPIO values, N=0..2\n" +help + "maxspeedN (18) GS max speed (steps per sec)\n" + "maxstepsN (21) GS max steps (from zero ESW)\n" + "mcut (7) G MCU T\n" + "mcuvdd (8) G MCU Vdd\n" + "microstepsN (16) GS microsteps settings (2^0..2^9)\n" + "minspeedN (19) min speed (steps per sec)\n" + "motcurrentN (46) GS motor current (1..32 for 1/32..32/32 of max current)\n" + "motflagsN (23) motorN flags\n" + "motmul* (36) GS external multiplexer status (<0 - disable, 0..7 - enable and set address)\n" + "motno (44) GS motor number for next `pdn` commands\n" + "motreinit (25) re-init motors after configuration changed\n" + "pdnN (43) GS read/write TMC2209 registers over uart @ motor0\n" + "ping (1)- echo given command back\n" + "relposN (27) GS relative move (get remaining)\n" + "relslowN (28) GS like 'relpos' but with slowest speed\n" + "reset (9) software reset\n" + "saveconf (13) save current configuration\n" + "screen* - GS screen enable (1) or disable (0)\n" + "speedlimit (20) G limiting speed for current microsteps setting\n" + "stateN (33) G motor state (0-relax, 1-accel, 2-move, 3-mvslow, 4-decel, 5-stall, 6-err)\n" + "stopN (30) stop motor with deceleration\n" + "time (10) G time from start (ms)\n" + "tmcbus* - GS TMC control bus (0 - USART, 1 - SPI)\n" + "udata* (39) GS data by usart in slave mode (text strings, '\\n'-terminated)\n" + "usartstatus* (40) GS status of USART1 (0 - off, 1 - master, 2 - slave)\n" + "vdrive (41) G approx voltage on Vdrive\n" + "vfive (42) G approx voltage on 5V bus\n" + +## CAN bus +Default CAN ID is 1. \ No newline at end of file diff --git a/F3:F303/Multistepper/can.c b/F3:F303/Multistepper/can.c index 9dc5069..f282ef8 100644 --- a/F3:F303/Multistepper/can.c +++ b/F3:F303/Multistepper/can.c @@ -37,6 +37,7 @@ static int8_t first_nonfree_idx = -1; // index of first data cell static uint16_t oldspeed = 100; // speed of last init uint32_t floodT = FLOOD_PERIOD_MS; // flood period in ms static uint8_t incrflood = 0; // ==1 for incremental flooding +static uint32_t incrmessagectr = 0; // counter for incremental flooding static uint32_t last_err_code = 0; static CAN_status can_status = CAN_STOP; @@ -130,7 +131,7 @@ so if TBS1=4 and TBS2=3, sum=8, bit sampling freq is 48/8 = 6MHz void CAN_setup(uint16_t speed){ if(speed == 0) speed = oldspeed; else if(speed < 50) speed = 50; - else if(speed > 3000) speed = 3000; + else if(speed > 1500) speed = 1500; oldspeed = speed; uint32_t tmout = 10000; /* Enable the peripheral clock CAN */ @@ -240,7 +241,6 @@ void CAN_proc(){ CAN_setup(0); } static uint32_t lastFloodTime = 0; - static uint32_t incrmessagectr = 0; if(flood_msg && (Tms - lastFloodTime) >= floodT){ // flood every ~5ms lastFloodTime = Tms; CAN_send(flood_msg->data, flood_msg->length, flood_msg->ID); @@ -305,8 +305,11 @@ CAN_status CAN_send(uint8_t *msg, uint8_t len, uint16_t target_id){ } void CAN_flood(CAN_message *msg, int incr){ - if(incr){ incrflood = 1; return; } - incrflood = 0; + if(incr){ + incrmessagectr = 0; + incrflood = 1; + return; + }else incrflood = 0; if(!msg) flood_msg = NULL; else{ memcpy(&loc_flood_msg, msg, sizeof(CAN_message)); diff --git a/F3:F303/Multistepper/commonproto.c b/F3:F303/Multistepper/commonproto.c index 872bf3d..9b10d57 100644 --- a/F3:F303/Multistepper/commonproto.c +++ b/F3:F303/Multistepper/commonproto.c @@ -108,6 +108,11 @@ errcodes cu_emstop(uint8_t _U_ par, int32_t _U_ *val){ return ERR_OK; } +errcodes cu_emstopall(uint8_t _U_ par, int32_t _U_ *val){ + for(int i = 0; i < MOTORSNO; ++i) emstopmotor(i); + return ERR_OK; +} + errcodes cu_eraseflash(uint8_t _U_ par, int32_t _U_ *val){ NOPARCHK(par); if(ISSETTER(par)){ diff --git a/F3:F303/Multistepper/commonproto.h b/F3:F303/Multistepper/commonproto.h index 40c6672..f21d245 100644 --- a/F3:F303/Multistepper/commonproto.h +++ b/F3:F303/Multistepper/commonproto.h @@ -113,6 +113,7 @@ errcodes cu_canid(uint8_t par, int32_t *val); errcodes cu_diagn(uint8_t par, int32_t *val); errcodes cu_drvtype(uint8_t par, int32_t *val); errcodes cu_emstop(uint8_t par, int32_t *val); +errcodes cu_emstopall(uint8_t par, int32_t *val); errcodes cu_eraseflash(uint8_t par, int32_t *val); errcodes cu_esw(uint8_t par, int32_t *val); errcodes cu_eswreact(uint8_t par, int32_t *val); diff --git a/F3:F303/Multistepper/flash.c b/F3:F303/Multistepper/flash.c index c120c35..0553832 100644 --- a/F3:F303/Multistepper/flash.c +++ b/F3:F303/Multistepper/flash.c @@ -32,12 +32,12 @@ 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 {.donthold = 1, .drvtype = DRVTYPE_UART} +#define DEFMF {.donthold = 1, .drvtype = DRVTYPE_SIMPLE} #define USERCONF_INITIALIZER { \ .userconf_sz = sizeof(user_conf) \ ,.CANspeed = 100 \ - ,.CANID = 0xaa \ + ,.CANID = 1 \ ,.microsteps = {32,32,32,32,32,32,32,32}\ ,.accel = {500,500,500,500,500,500,500,500} \ ,.maxspd = {2000,2000,2000,2000,2000,2000,2000,2000} \ @@ -203,8 +203,8 @@ int erase_storage(int npage){ int fn_dumpconf(uint32_t _U_ hash, char _U_ *args){ // "dumpconf" (3271513185) #ifdef EBUG - USB_sendstr("flashsize="); printu(FLASH_SIZE); USB_putbyte('*'); - printu(FLASH_blocksize); USB_putbyte('='); printu(FLASH_SIZE*FLASH_blocksize); + USB_sendstr("flashsize="); printu(FLASH_SIZE); USB_sendstr("kB\nblocksize="); + printu(FLASH_blocksize); newline(); #endif USB_sendstr("userconf_addr="); printuhex((uint32_t)Flash_Data); @@ -230,7 +230,7 @@ int fn_dumpconf(uint32_t _U_ hash, char _U_ *args){ // "dumpconf" (3271513185) printu(the_conf.motcurrent[i]); PROPNAME("motflags"); printuhex(*((uint8_t*)&the_conf.motflags[i])); - PROPNAME("eswreaction"); + PROPNAME("eswreact"); printu(the_conf.ESW_reaction[i]); #undef PROPNAME } diff --git a/F3:F303/Multistepper/flash.h b/F3:F303/Multistepper/flash.h index c59322b..26e5426 100644 --- a/F3:F303/Multistepper/flash.h +++ b/F3:F303/Multistepper/flash.h @@ -63,6 +63,7 @@ typedef struct{ * struct to save user configurations */ typedef struct __attribute__((packed, aligned(4))){ + uint32_t maxsteps[MOTORSNO]; // maximal amount of steps uint16_t userconf_sz; // "magick number" uint16_t CANspeed; // default CAN speed uint16_t CANID; // identifier @@ -70,11 +71,9 @@ typedef struct __attribute__((packed, aligned(4))){ 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 motflags_t motflags[MOTORSNO]; // motor's flags uint8_t ESW_reaction[MOTORSNO]; // end-switches reaction (esw_react) uint8_t motcurrent[MOTORSNO]; // IRUN as fraction of max current (1..32) - uint8_t isSPI; // ==1 if there's SPI drivers instead of UART } user_conf; extern user_conf the_conf; // global user config (read from FLASH to RAM) diff --git a/F3:F303/Multistepper/hardware.c b/F3:F303/Multistepper/hardware.c index 940d6e0..3fe8aee 100644 --- a/F3:F303/Multistepper/hardware.c +++ b/F3:F303/Multistepper/hardware.c @@ -76,7 +76,7 @@ static IRQn_Type motirqs[MOTORSNO] = { // return two bits: 0 - ESW0, 1 - ESW1 (if inactive -> 1; if active -> 0) uint8_t ESW_state(uint8_t MOTno){ uint8_t val = 0; - if(the_conf.isSPI){ // only ESW0 used + if(the_conf.motflags[MOTno].drvtype == DRVTYPE_SPI){ // only ESW0 used val = ((ESWports[MOTno][0]->IDR & ESWpins[MOTno][0]) ? 1 : 0); if(the_conf.motflags[MOTno].eswinv) val ^= 1; return val; diff --git a/F3:F303/Multistepper/hashgen/hashgen.c b/F3:F303/Multistepper/hashgen/hashgen.c index a708d39..ac30ac6 100644 --- a/F3:F303/Multistepper/hashgen/hashgen.c +++ b/F3:F303/Multistepper/hashgen/hashgen.c @@ -170,14 +170,13 @@ static char *fnname(const char *cmd){ static const char *fhdr = "int parsecmd(const char *str){\n\ - char cmd[CMD_MAXLEN + 1];\n\ if(!str || !*str) return RET_CMDNOTFOUND;\n\ int i = 0;\n\ - while(*str > '@' && i < CMD_MAXLEN){ cmd[i++] = *str++; }\n\ - cmd[i] = 0;\n\ + while(*str > '@' && i < CMD_MAXLEN){ lastcmd[i++] = *str++; }\n\ + lastcmd[i] = 0;\n\ while(*str && *str <= ' ') ++str;\n\ char *args = (char*) str;\n\ - uint32_t h = hashf(cmd);\n\ + uint32_t h = hashf(lastcmd);\n\ switch(h){\n\n" ; static const char *ffooter = @@ -195,12 +194,15 @@ static const char *headercontent = #endif\n\n\ #define CMD_MAXLEN (32)\n\n\ enum{\n\ + RET_HELP = -3,\n\ RET_CMDNOTFOUND = -2,\n\ RET_WRONGCMD = -1,\n\ - RET_BAD = 0,\n\ - RET_GOOD = 1\n\ + RET_GOOD = 0,\n\ + RET_BAD = 1\n\ };\n\n\ -int parsecmd(const char *cmdwargs);\n\n"; +int parsecmd(const char *cmdwargs);\n\n\ +extern char lastcmd[];\n\n"; + static const char *sw = " case CMD_%s:\n\ return fn_%s(h, args);\n\ @@ -213,7 +215,8 @@ static const char *srchdr = #include \"%s\"\n\n\ #ifndef WAL\n\ #define WAL __attribute__ ((weak, alias (\"__f1\")))\n\ -#endif\n\nstatic int __f1(uint32_t _U_ h, char _U_ *a){return 1;}\n\n" +#endif\n\nstatic int __f1(uint32_t _U_ h, char _U_ *a){return 1;}\n\n\ +char lastcmd[CMD_MAXLEN + 1];\n\n" ; static void build(strhash *H, int hno, int hlen){ diff --git a/F3:F303/Multistepper/hashgen/hdr.c b/F3:F303/Multistepper/hashgen/hdr.c index 2d59d0f..b3a39ba 100644 --- a/F3:F303/Multistepper/hashgen/hdr.c +++ b/F3:F303/Multistepper/hashgen/hdr.c @@ -8,10 +8,10 @@ #define WAL __attribute__ ((weak, alias ("__f1"))) #endif -char lastcmd[CMD_MAXLEN + 1]; - static int __f1(uint32_t _U_ h, char _U_ *a){return 1;} +char lastcmd[CMD_MAXLEN + 1]; + int fn_abspos(uint32_t _U_ hash, char _U_ *args) WAL; // "abspos" (3056382221) int fn_accel(uint32_t _U_ hash, char _U_ *args) WAL; // "accel" (1490521981) @@ -76,6 +76,8 @@ int fn_gpio(uint32_t _U_ hash, char _U_ *args) WAL; // "gpio" (4286324660) int fn_gpioconf(uint32_t _U_ hash, char _U_ *args) WAL; // "gpioconf" (1309721562) +int fn_help(uint32_t _U_ hash, char _U_ *args) WAL; // "help" (4288288686) + int fn_maxspeed(uint32_t _U_ hash, char _U_ *args) WAL; // "maxspeed" (1498078812) int fn_maxsteps(uint32_t _U_ hash, char _U_ *args) WAL; // "maxsteps" (1506667002) @@ -244,6 +246,9 @@ int parsecmd(const char *str){ case CMD_GPIOCONF: return fn_gpioconf(h, args); break; + case CMD_HELP: + return fn_help(h, args); + break; case CMD_MAXSPEED: return fn_maxspeed(h, args); break; diff --git a/F3:F303/Multistepper/hashgen/hdr.h b/F3:F303/Multistepper/hashgen/hdr.h index 202d42f..1bd8555 100644 --- a/F3:F303/Multistepper/hashgen/hdr.h +++ b/F3:F303/Multistepper/hashgen/hdr.h @@ -5,10 +5,11 @@ #define CMD_MAXLEN (32) enum{ + RET_HELP = -3, RET_CMDNOTFOUND = -2, RET_WRONGCMD = -1, - RET_BAD = 0, - RET_GOOD = 1 + RET_GOOD = 0, + RET_BAD = 1 }; int parsecmd(const char *cmdwargs); @@ -47,6 +48,7 @@ extern char lastcmd[]; #define CMD_GOTOZ (3178103736) #define CMD_GPIO (4286324660) #define CMD_GPIOCONF (1309721562) +#define CMD_HELP (4288288686) #define CMD_MAXSPEED (1498078812) #define CMD_MAXSTEPS (1506667002) #define CMD_MCUT (4022718) diff --git a/F3:F303/Multistepper/hashgen/helpcmds.in b/F3:F303/Multistepper/hashgen/helpcmds.in index d03b2aa..23e2d78 100644 --- a/F3:F303/Multistepper/hashgen/helpcmds.in +++ b/F3:F303/Multistepper/hashgen/helpcmds.in @@ -30,6 +30,7 @@ "gotozN - find zero position & refresh counters\n" "gpioconfN* - GS GPIO configuration (0 - PUin, 1 - PPout, 2 - ODout), N=0..2\n" "gpioN* - GS GPIO values, N=0..2\n" + "help - print this help\n" "maxspeedN - GS max speed (steps per sec)\n" "maxstepsN - GS max steps (from zero ESW)\n" "mcut - G MCU T\n" diff --git a/F3:F303/Multistepper/hashgen/run b/F3:F303/Multistepper/hashgen/run index e79297c..a041db4 100755 --- a/F3:F303/Multistepper/hashgen/run +++ b/F3:F303/Multistepper/hashgen/run @@ -8,3 +8,5 @@ gcc hdr.c test.c strfunc.c -o test ./test "esw45 = some text" ./test "goto 55 = " ./test "stop 3256" +./test "mcut" + diff --git a/F3:F303/Multistepper/hashgen/test b/F3:F303/Multistepper/hashgen/test new file mode 100755 index 0000000..8fae8fc Binary files /dev/null and b/F3:F303/Multistepper/hashgen/test differ diff --git a/F3:F303/Multistepper/hashgen/test.c b/F3:F303/Multistepper/hashgen/test.c index 3dc0dda..fce0292 100644 --- a/F3:F303/Multistepper/hashgen/test.c +++ b/F3:F303/Multistepper/hashgen/test.c @@ -7,9 +7,9 @@ static int noargs(uint32_t hash){ switch(hash){ - case CMD_REBOOT: printf("REBOOT\n"); break; + case CMD_RESET: printf("REBOOT\n"); break; case CMD_TIME: printf("TIME!\n"); break; - case CMD_TEMP: printf("Temp\n"); break; + case CMD_MCUT: printf("Temp\n"); break; default: printf("Unknown hash 0x%x\n", hash); return 0; } return 1; @@ -30,7 +30,7 @@ static int withparno(uint32_t hash, char *args){ switch(hash){ case CMD_ESW: fname = "ESW"; break; case CMD_GOTO: fname = "GOTO"; break; - case CMD_POS: fname = "POS"; break; + case CMD_ABSPOS: fname = "ABSPOS"; break; case CMD_STOP: fname = "STOP"; break; default: fname = "unknown"; } diff --git a/F3:F303/Multistepper/hashgen/testdic b/F3:F303/Multistepper/hashgen/testdic index daaab7e..0fe640b 100644 --- a/F3:F303/Multistepper/hashgen/testdic +++ b/F3:F303/Multistepper/hashgen/testdic @@ -30,6 +30,7 @@ goto gotoz gpioconf gpio +help maxspeed maxsteps mcut diff --git a/F3:F303/Multistepper/multistepper.bin b/F3:F303/Multistepper/multistepper.bin index f06205d..97ee936 100755 Binary files a/F3:F303/Multistepper/multistepper.bin and b/F3:F303/Multistepper/multistepper.bin differ diff --git a/F3:F303/Multistepper/proto.c b/F3:F303/Multistepper/proto.c index 34b9317..27ef830 100644 --- a/F3:F303/Multistepper/proto.c +++ b/F3:F303/Multistepper/proto.c @@ -288,6 +288,7 @@ int fn_canfilter(uint32_t _U_ hash, char *args){ int fn_canflood(uint32_t _U_ hash, char *args){ CAN_flood(parseCANmsg(args), 0); + USB_sendstr("Simple flooding is ON (send with empty ID to stop)\n"); return RET_GOOD; } @@ -333,8 +334,8 @@ int fn_canerrcodes(uint32_t _U_ hash, char _U_ *args){ } int fn_canincrflood(uint32_t _U_ hash, char _U_ *args){ - CAN_flood(NULL, 1); - USB_sendstr("Incremental flooding is ON ('F' to off)\n"); + CAN_flood(parseCANmsg(args), 1); + USB_sendstr("Incremental flooding is ON (send with empty ID to stop)\n"); return RET_GOOD; } @@ -346,18 +347,17 @@ int fn_canspeed(uint32_t _U_ hash, char _U_ *args){ return RET_GOOD; } if(N < 50){ - USB_sendstr("canspeed="); - USB_sendstr(u2str(CAN_speed())); - newline(); + USND("Lower speed is 50kbps"); return RET_GOOD; - }else if(N > 3000){ - USB_sendstr("Highest speed is 3000kbps"); + }else if(N > 1500){ + USND("Highest speed is 1500kbps"); return RET_GOOD; } CAN_reinit((uint16_t)N); - // theconf.canspeed = N; + uint32_t regval = 4500 / N; + the_conf.CANspeed = 4500 * regval; USB_sendstr("Reinit CAN bus with speed "); - printu(N); USB_sendstr("kbps"); newline(); + printu(the_conf.CANspeed); USB_sendstr("kbps"); newline(); return RET_GOOD; } @@ -529,7 +529,8 @@ static int canusb_function(uint32_t hash, char *args){ } USB_sendstr("button"); USB_putbyte('0'+PARBASE(par)); USB_putbyte('='); USB_sendstr(kstate); - USB_sendstr("\nbuttontm="); USB_sendstr(u2str(val)); + USB_sendstr("\nbuttontm"); USB_putbyte('0'+PARBASE(par)); + USB_putbyte('='); USB_sendstr(u2str(val)); newline(); return RET_GOOD; break; @@ -552,7 +553,9 @@ static int canusb_function(uint32_t hash, char *args){ e = cu_drvtype(par, &val); break; case CMD_EMSTOP: - e = cu_emstop(par, &val); + if(par == CANMESG_NOPAR) e = cu_emstopall(par, &val); + else e = cu_emstop(par, &val); + if(e == ERR_OK){ USND("OK"); return RET_GOOD;} break; case CMD_ESWREACT: e = cu_eswreact(par, &val); @@ -682,6 +685,7 @@ int fn_goto(uint32_t _U_ hash, char _U_ *args) AL; //* "goto" (4286309438) int fn_gotoz(uint32_t _U_ hash, char _U_ *args) AL; //* "gotoz" (3178103736) int fn_gpio(uint32_t _U_ hash, char _U_ *args) AL; //* "gpio" (4286324660) int fn_gpioconf(uint32_t _U_ hash, char _U_ *args) AL; //* "gpioconf" (1309721562) +int fn_help(uint32_t _U_ hash, char _U_ *args){return RET_HELP;} // "help" (4288288686) int fn_maxspeed(uint32_t _U_ hash, char _U_ *args) AL; //* "maxspeed" (1498078812) int fn_maxsteps(uint32_t _U_ hash, char _U_ *args) AL; //* "maxsteps" (1506667002) int fn_mcut(uint32_t _U_ hash, char _U_ *args) AL; // "mcut" (4022718) @@ -717,8 +721,9 @@ int fn_vfive(uint32_t _U_ hash, char _U_ *args) AL; // "vfive" (3017477285) const char *cmd_parser(const char *txt){ int ret = parsecmd(txt); switch(ret){ - case RET_CMDNOTFOUND: return helpstring; break; - case RET_WRONGCMD: return "Wrong command parameters\n"; break; + case RET_HELP: return helpstring; break; + case RET_CMDNOTFOUND: return "BADCMD\n"; break; + case RET_WRONGCMD: return "BADARGS\n"; break; case RET_GOOD: return NULL; break; default: return "FAIL\n"; break; } diff --git a/F3:F303/Multistepper/version.inc b/F3:F303/Multistepper/version.inc index a6f8163..d05e2b0 100644 --- a/F3:F303/Multistepper/version.inc +++ b/F3:F303/Multistepper/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "114" -#define BUILD_DATE "2024-08-15" +#define BUILD_NUMBER "119" +#define BUILD_DATE "2024-08-16"