fixed USBDP pullup in Multistepper (it works always, so you can use DFU)

This commit is contained in:
Edward Emelianov
2023-02-06 20:05:45 +03:00
parent 756ed4be08
commit daf17a651e
54 changed files with 12332 additions and 9328 deletions

View File

@@ -0,0 +1 @@
file helpcmds.in includes into proto.c as help list

View File

@@ -0,0 +1,318 @@
/*
* Copyright 2022 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 <stdio.h>
#include <string.h>
#include <usefull_macros.h>
#include <ctype.h>
#define ALLOCSZ (5000)
typedef struct{
char *dict;
char *headerfile;
char *sourcefile;
int genfunc;
} glob_pars;
static glob_pars G = {.headerfile = "hash.h", .sourcefile = "hash.c"};
static int help = 0;
static myoption cmdlnopts[] = {
{"help", NO_ARGS, NULL, 'h', arg_int, APTR(&help), "show this help"},
{"dict", NEED_ARG, NULL, 'd', arg_string, APTR(&G.dict), "dictionary file"},
{"header", NEED_ARG, NULL, 'H', arg_string, APTR(&G.headerfile),"output header filename"},
{"source", NEED_ARG, NULL, 'S', arg_string, APTR(&G.sourcefile),"output source filename"},
{"genfunc", NO_ARGS, NULL, 'F', arg_int, APTR(&G.genfunc), "generate function bodys"},
end_option
};
static void parse_args(int argc, char **argv){
parseargs(&argc, &argv, cmdlnopts);
if(help) showhelp(-1, cmdlnopts);
if(argc > 0){
red("Unused arguments:\n");
for(int i = 0; i < argc; ++i)
printf("%s ", argv[i]);
printf("\n");
showhelp(-1, cmdlnopts);
}
}
#define HASHFNO (3)
// djb2 & sdbm: http://www.cse.yorku.ca/~oz/hash.html
static uint32_t djb2(const char *str){
uint32_t hash = 5381;
uint32_t c;
while((c = (uint32_t)*str++))
hash = ((hash << 7) + hash) + c;
//hash = hash * 31 + c;
//hash = hash * 33 + c;
return hash;
}
static uint32_t sdbm(const char *str){
uint32_t hash = 5381;
uint32_t c;
while((c = (uint32_t)*str++))
hash = c + (hash << 6) + (hash << 16) - hash;
return hash;
}
// jenkins: https://en.wikipedia.org/wiki/Jenkins_hash_function
static uint32_t jenkins(const char *str){
uint32_t hash = 0, c;
while((c = (uint32_t)*str++)){
hash += c;
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return hash;
}
static const char *hashsources[HASHFNO] = {
"static uint32_t hashf(const char *str){\n\
uint32_t hash = 5381;\n\
uint32_t c;\n\
while((c = (uint32_t)*str++))\n\
hash = ((hash << 7) + hash) + c;\n\
return hash;\n\
}\n",
"static uint32_t hashf(const char *str){\n\
uint32_t hash = 5381;\n\
uint32_t c;\n\
while((c = (uint32_t)*str++))\n\
hash = c + (hash << 6) + (hash << 16) - hash;\n\
return hash;\n\
}\n",
"static uint32_t hashf(const char *str){\n\
uint32_t hash = 0, c;\n\
while((c = (uint32_t)*str++)){\n\
hash += c;\n\
hash += (hash << 10);\n\
hash ^= (hash >> 6);\n\
}\n\
hash += (hash << 3);\n\
hash ^= (hash >> 11);\n\
hash += (hash << 15);\n\
return hash;\n\
}\n"
};
static uint32_t (*hash[HASHFNO])(const char *str) = {djb2, sdbm, jenkins};
static const char *hashnames[HASHFNO] = {"DJB2", "SDBM", "Jenkins"};
typedef struct{
char str[32]; // string command
char fname[32]; // function namee
uint32_t hash; // command hash
} strhash;
static int sorthashesH(const void *a, const void *b){ // sort by hash
register uint32_t h1 = ((strhash*)a)->hash, h2 = ((strhash*)b)->hash;
if(h1 > h2) return 1;
else if(h1 < h2) return -1;
return 0;
}
static int sorthashesS(const void *a, const void *b){ // sort by string
char *s1 = ((strhash*)a)->str, *s2 = ((strhash*)b)->str;
return strcmp(s1, s2);
}
static int sorthashesF(const void *a, const void *b){ // sort by fname
char *s1 = ((strhash*)a)->fname, *s2 = ((strhash*)b)->fname;
return strcmp(s1, s2);
}
static FILE *openoutp(const char *name){
FILE *f = fopen(name, "w");
if(!f) ERR("Can't open file %s", name);
return f;
}
static char *macroname(const char *cmd){
static char macro[32];
int i = 0;
while(i < 31 && *cmd){
char c = *cmd++;
if(!isalnum(c)) c = '_';
if(islower(c)) c = toupper(c);
macro[i++] = c;
}
macro[i] = 0;
return macro;
}
static char *fnname(const char *cmd){
static char fn[32];
int i = 0;
while(i < 31 && *cmd){
char c = *cmd++;
if(!isalpha(c)) c = '_';
if(isupper(c)) c = tolower(c);
fn[i++] = c;
}
fn[i] = 0;
return fn;
}
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\
if(*str){\n\
while(*str <= ' ') ++str;\n\
}\n\
char *args = (char*) str;\n\
uint32_t h = hashf(cmd);\n\
switch(h){\n\n"
;
static const char *ffooter =
" default: break;\n\
}\n\
return RET_CMDNOTFOUND;\n\
}\n\n"
;
static const char *fns =
"int fn_%s(_U_ uint32_t hash, _U_ char *args) WAL; // \"%s\" (%u)\n\n"
;
static const char *headercontent =
"#ifndef _U_\n\
#define _U_ __attribute__((__unused__))\n\
#endif\n\n\
#define CMD_MAXLEN (32)\n\n\
enum{\n\
RET_CMDNOTFOUND = -2,\n\
RET_WRONGCMD = -1,\n\
RET_BAD = 0,\n\
RET_GOOD = 1\n\
};\n\n\
int parsecmd(const char *cmdwargs);\n\n";
static const char *sw =
" case CMD_%s:\n\
return fn_%s(h, args);\n\
break;\n";
static const char *srchdr =
"// Generated by HASHGEN (https://github.com/eddyem/eddys_snippets/tree/master/stringHash4MCU_)\n\
// Licensed by GPLv3\n\
#include <stdint.h>\n\
#include <stddef.h>\n\
#include \"%s\"\n\n\
#ifndef WAL\n\
#define WAL __attribute__ ((weak, alias (\"__f1\")))\n\
#endif\n\nstatic int __f1(_U_ uint32_t h, _U_ char *a){return 1;}\n\n"
;
static void build(strhash *H, int hno, int hlen){
green("Generate files for hash function '%s'\n", hashnames[hno]);
int lmax = 1;
for(int i = 0; i < hlen; ++i){
int l = strlen(H[i].str);
if(l > lmax){
lmax = l;
}
}
lmax = (lmax + 3)/4;
lmax *= 4;
// resort H by strings
qsort(H, hlen, sizeof(strhash), sorthashesS);
FILE *source = openoutp(G.sourcefile), *header = openoutp(G.headerfile);
fprintf(source, srchdr, G.headerfile);
if(G.genfunc){
for(int i = 0; i < hlen; ++i){
fprintf(source, fns, H[i].fname, H[i].str, H[i].hash);
}
}
fprintf(header, "%s", headercontent);
fprintf(source, "%s\n", hashsources[hno]);
fprintf(source, "%s", fhdr);
for(int i = 0; i < hlen; ++i){
char *m = macroname(H[i].str);
fprintf(source, sw, m, H[i].fname);
fprintf(header, "#define CMD_%-*s (%u)\n", lmax, m, H[i].hash);
}
fprintf(source, "%s", ffooter);
fclose(source);
fclose(header);
}
int main(int argc, char **argv){
initial_setup();
parse_args(argc, argv);
if(!G.dict) ERRX("point dictionary file");
if(!G.headerfile) ERRX("point header source file");
if(!G.sourcefile) ERRX("point c source file");
mmapbuf *b = My_mmap(G.dict);
if(!b) ERRX("Can't open %s", G.dict);
char *word = b->data;
strhash *H = MALLOC(strhash, ALLOCSZ);
int l = ALLOCSZ, idx = 0;
while(*word){
if(idx >= l){
l += ALLOCSZ;
H = realloc(H, sizeof(strhash) * l);
if(!H) ERR("realloc()");
}
while(*word && *word < 33) ++word;
if(!*word) break;
char *nxt = strchr(word, '\n');
if(nxt){
int len = nxt - word;
if(len > 31) len = 31;
strncpy(H[idx].str, word, len);
H[idx].str[len] = 0;
}else{
snprintf(H[idx].str, 31, "%s", word);
}
snprintf(H[idx].fname, 31, "%s", fnname(H[idx].str));
++idx;
if(!nxt) break;
word = nxt + 1;
}
// test fname matches
qsort(H, idx, sizeof(strhash), sorthashesF);
int mflag = 0;
int imax1 = idx - 1, hno = 0;
for(int i = 0; i < imax1; ++i){ // test hash matches
if(0 == strcmp(H[i].fname, H[i+1].fname)){
mflag = 1;
WARNX("Have two similar function names for '%s' and '%s': 'fn_%s'",
H[i].str, H[i+1].str, H[i].fname);
}
}
if(mflag) ERRX("Can't generate code when names of some functions matches");
for(; hno < HASHFNO; ++hno){
for(int i = 0; i < idx; ++i)
H[i].hash = hash[hno](H[i].str);
qsort(H, idx, sizeof(strhash), sorthashesH);
strhash *p = H;
int nmatches = 0;
for(int i = 0; i < imax1; ++i, ++p){ // test hash matches
if(p->hash == p[1].hash) ++nmatches;
}
if(nmatches == 0){
build(H, hno, idx);
break;
}
WARNX("Function '%s' have %d matches", hashnames[hno], nmatches);
}
if(hno == HASHFNO) WARNX("Can't find proper hash function");
FREE(H);
My_munmap(b);
return 0;
}

View File

@@ -0,0 +1,318 @@
// Generated by HASHGEN (https://github.com/eddyem/eddys_snippets/tree/master/stringHash4MCU_)
// Licensed by GPLv3
#include <stdint.h>
#include <stddef.h>
#include "hdr.h"
#ifndef WAL
#define WAL __attribute__ ((weak, alias ("__f1")))
#endif
static int __f1(_U_ uint32_t h, _U_ char *a){return 1;}
int fn_abspos(_U_ uint32_t hash, _U_ char *args) WAL; // "abspos" (3056382221)
int fn_accel(_U_ uint32_t hash, _U_ char *args) WAL; // "accel" (1490521981)
int fn_adc(_U_ uint32_t hash, _U_ char *args) WAL; // "adc" (2963026093)
int fn_button(_U_ uint32_t hash, _U_ char *args) WAL; // "button" (1093508897)
int fn_canerrcodes(_U_ uint32_t hash, _U_ char *args) WAL; // "canerrcodes" (1736697870)
int fn_canfilter(_U_ uint32_t hash, _U_ char *args) WAL; // "canfilter" (3964416573)
int fn_canflood(_U_ uint32_t hash, _U_ char *args) WAL; // "canflood" (1235816779)
int fn_canfloodt(_U_ uint32_t hash, _U_ char *args) WAL; // "canfloodT" (506574623)
int fn_canid(_U_ uint32_t hash, _U_ char *args) WAL; // "canid" (2040257924)
int fn_canignore(_U_ uint32_t hash, _U_ char *args) WAL; // "canignore" (3209755195)
int fn_canincrflood(_U_ uint32_t hash, _U_ char *args) WAL; // "canincrflood" (3987155959)
int fn_canpause(_U_ uint32_t hash, _U_ char *args) WAL; // "canpause" (3981532373)
int fn_canreinit(_U_ uint32_t hash, _U_ char *args) WAL; // "canreinit" (2030075842)
int fn_canresume(_U_ uint32_t hash, _U_ char *args) WAL; // "canresume" (2051659720)
int fn_cansend(_U_ uint32_t hash, _U_ char *args) WAL; // "cansend" (237136225)
int fn_canspeed(_U_ uint32_t hash, _U_ char *args) WAL; // "canspeed" (549265992)
int fn_canstat(_U_ uint32_t hash, _U_ char *args) WAL; // "canstat" (237384179)
int fn_delignlist(_U_ uint32_t hash, _U_ char *args) WAL; // "delignlist" (2235834164)
int fn_diagn(_U_ uint32_t hash, _U_ char *args) WAL; // "diagn" (2334137736)
int fn_dumpcmd(_U_ uint32_t hash, _U_ char *args) WAL; // "dumpcmd" (1223955823)
int fn_dumpconf(_U_ uint32_t hash, _U_ char *args) WAL; // "dumpconf" (3271513185)
int fn_dumperr(_U_ uint32_t hash, _U_ char *args) WAL; // "dumperr" (1223989764)
int fn_emstop(_U_ uint32_t hash, _U_ char *args) WAL; // "emstop" (2965919005)
int fn_encpos(_U_ uint32_t hash, _U_ char *args) WAL; // "encpos" (3208428301)
int fn_encrev(_U_ uint32_t hash, _U_ char *args) WAL; // "encrev" (3208460296)
int fn_encstepmax(_U_ uint32_t hash, _U_ char *args) WAL; // "encstepmax" (1022989757)
int fn_encstepmin(_U_ uint32_t hash, _U_ char *args) WAL; // "encstepmin" (1022990779)
int fn_eraseflash(_U_ uint32_t hash, _U_ char *args) WAL; // "eraseflash" (3177247267)
int fn_esw(_U_ uint32_t hash, _U_ char *args) WAL; // "esw" (2963094612)
int fn_eswreact(_U_ uint32_t hash, _U_ char *args) WAL; // "eswreact" (1614224995)
int fn_goto(_U_ uint32_t hash, _U_ char *args) WAL; // "goto" (4286309438)
int fn_gotoz(_U_ uint32_t hash, _U_ char *args) WAL; // "gotoz" (3178103736)
int fn_gpio(_U_ uint32_t hash, _U_ char *args) WAL; // "gpio" (4286324660)
int fn_gpioconf(_U_ uint32_t hash, _U_ char *args) WAL; // "gpioconf" (1309721562)
int fn_maxspeed(_U_ uint32_t hash, _U_ char *args) WAL; // "maxspeed" (1498078812)
int fn_maxsteps(_U_ uint32_t hash, _U_ char *args) WAL; // "maxsteps" (1506667002)
int fn_mcut(_U_ uint32_t hash, _U_ char *args) WAL; // "mcut" (4022718)
int fn_mcuvdd(_U_ uint32_t hash, _U_ char *args) WAL; // "mcuvdd" (2517587080)
int fn_microsteps(_U_ uint32_t hash, _U_ char *args) WAL; // "microsteps" (3974395854)
int fn_minspeed(_U_ uint32_t hash, _U_ char *args) WAL; // "minspeed" (3234848090)
int fn_motflags(_U_ uint32_t hash, _U_ char *args) WAL; // "motflags" (2153634658)
int fn_motmul(_U_ uint32_t hash, _U_ char *args) WAL; // "motmul" (1543400099)
int fn_motreinit(_U_ uint32_t hash, _U_ char *args) WAL; // "motreinit" (199682784)
int fn_ping(_U_ uint32_t hash, _U_ char *args) WAL; // "ping" (10561715)
int fn_relpos(_U_ uint32_t hash, _U_ char *args) WAL; // "relpos" (1278646042)
int fn_relslow(_U_ uint32_t hash, _U_ char *args) WAL; // "relslow" (1742971917)
int fn_reset(_U_ uint32_t hash, _U_ char *args) WAL; // "reset" (1907803304)
int fn_saveconf(_U_ uint32_t hash, _U_ char *args) WAL; // "saveconf" (141102426)
int fn_screen(_U_ uint32_t hash, _U_ char *args) WAL; // "screen" (2100809349)
int fn_speedlimit(_U_ uint32_t hash, _U_ char *args) WAL; // "speedlimit" (1654184245)
int fn_state(_U_ uint32_t hash, _U_ char *args) WAL; // "state" (2216628902)
int fn_stop(_U_ uint32_t hash, _U_ char *args) WAL; // "stop" (17184971)
int fn_time(_U_ uint32_t hash, _U_ char *args) WAL; // "time" (19148340)
int fn_tmcbus(_U_ uint32_t hash, _U_ char *args) WAL; // "tmcbus" (1906135955)
int fn_udata(_U_ uint32_t hash, _U_ char *args) WAL; // "udata" (2736127636)
int fn_usartstatus(_U_ uint32_t hash, _U_ char *args) WAL; // "usartstatus" (4007098968)
static uint32_t hashf(const char *str){
uint32_t hash = 5381;
uint32_t c;
while((c = (uint32_t)*str++))
hash = ((hash << 7) + hash) + c;
return hash;
}
int parsecmd(const char *str){
char cmd[CMD_MAXLEN + 1];
if(!str || !*str) return RET_CMDNOTFOUND;
int i = 0;
while(*str > '@' && i < CMD_MAXLEN){ cmd[i++] = *str++; }
cmd[i] = 0;
if(*str){
while(*str <= ' ') ++str;
}
char *args = (char*) str;
uint32_t h = hashf(cmd);
switch(h){
case CMD_ABSPOS:
return fn_abspos(h, args);
break;
case CMD_ACCEL:
return fn_accel(h, args);
break;
case CMD_ADC:
return fn_adc(h, args);
break;
case CMD_BUTTON:
return fn_button(h, args);
break;
case CMD_CANERRCODES:
return fn_canerrcodes(h, args);
break;
case CMD_CANFILTER:
return fn_canfilter(h, args);
break;
case CMD_CANFLOOD:
return fn_canflood(h, args);
break;
case CMD_CANFLOODT:
return fn_canfloodt(h, args);
break;
case CMD_CANID:
return fn_canid(h, args);
break;
case CMD_CANIGNORE:
return fn_canignore(h, args);
break;
case CMD_CANINCRFLOOD:
return fn_canincrflood(h, args);
break;
case CMD_CANPAUSE:
return fn_canpause(h, args);
break;
case CMD_CANREINIT:
return fn_canreinit(h, args);
break;
case CMD_CANRESUME:
return fn_canresume(h, args);
break;
case CMD_CANSEND:
return fn_cansend(h, args);
break;
case CMD_CANSPEED:
return fn_canspeed(h, args);
break;
case CMD_CANSTAT:
return fn_canstat(h, args);
break;
case CMD_DELIGNLIST:
return fn_delignlist(h, args);
break;
case CMD_DIAGN:
return fn_diagn(h, args);
break;
case CMD_DUMPCMD:
return fn_dumpcmd(h, args);
break;
case CMD_DUMPCONF:
return fn_dumpconf(h, args);
break;
case CMD_DUMPERR:
return fn_dumperr(h, args);
break;
case CMD_EMSTOP:
return fn_emstop(h, args);
break;
case CMD_ENCPOS:
return fn_encpos(h, args);
break;
case CMD_ENCREV:
return fn_encrev(h, args);
break;
case CMD_ENCSTEPMAX:
return fn_encstepmax(h, args);
break;
case CMD_ENCSTEPMIN:
return fn_encstepmin(h, args);
break;
case CMD_ERASEFLASH:
return fn_eraseflash(h, args);
break;
case CMD_ESW:
return fn_esw(h, args);
break;
case CMD_ESWREACT:
return fn_eswreact(h, args);
break;
case CMD_GOTO:
return fn_goto(h, args);
break;
case CMD_GOTOZ:
return fn_gotoz(h, args);
break;
case CMD_GPIO:
return fn_gpio(h, args);
break;
case CMD_GPIOCONF:
return fn_gpioconf(h, args);
break;
case CMD_MAXSPEED:
return fn_maxspeed(h, args);
break;
case CMD_MAXSTEPS:
return fn_maxsteps(h, args);
break;
case CMD_MCUT:
return fn_mcut(h, args);
break;
case CMD_MCUVDD:
return fn_mcuvdd(h, args);
break;
case CMD_MICROSTEPS:
return fn_microsteps(h, args);
break;
case CMD_MINSPEED:
return fn_minspeed(h, args);
break;
case CMD_MOTFLAGS:
return fn_motflags(h, args);
break;
case CMD_MOTMUL:
return fn_motmul(h, args);
break;
case CMD_MOTREINIT:
return fn_motreinit(h, args);
break;
case CMD_PING:
return fn_ping(h, args);
break;
case CMD_RELPOS:
return fn_relpos(h, args);
break;
case CMD_RELSLOW:
return fn_relslow(h, args);
break;
case CMD_RESET:
return fn_reset(h, args);
break;
case CMD_SAVECONF:
return fn_saveconf(h, args);
break;
case CMD_SCREEN:
return fn_screen(h, args);
break;
case CMD_SPEEDLIMIT:
return fn_speedlimit(h, args);
break;
case CMD_STATE:
return fn_state(h, args);
break;
case CMD_STOP:
return fn_stop(h, args);
break;
case CMD_TIME:
return fn_time(h, args);
break;
case CMD_TMCBUS:
return fn_tmcbus(h, args);
break;
case CMD_UDATA:
return fn_udata(h, args);
break;
case CMD_USARTSTATUS:
return fn_usartstatus(h, args);
break;
default: break;
}
return RET_CMDNOTFOUND;
}

View File

@@ -0,0 +1,71 @@
#ifndef _U_
#define _U_ __attribute__((__unused__))
#endif
#define CMD_MAXLEN (32)
enum{
RET_CMDNOTFOUND = -2,
RET_WRONGCMD = -1,
RET_BAD = 0,
RET_GOOD = 1
};
int parsecmd(const char *cmdwargs);
#define CMD_ABSPOS (3056382221)
#define CMD_ACCEL (1490521981)
#define CMD_ADC (2963026093)
#define CMD_BUTTON (1093508897)
#define CMD_CANERRCODES (1736697870)
#define CMD_CANFILTER (3964416573)
#define CMD_CANFLOOD (1235816779)
#define CMD_CANFLOODT (506574623)
#define CMD_CANID (2040257924)
#define CMD_CANIGNORE (3209755195)
#define CMD_CANINCRFLOOD (3987155959)
#define CMD_CANPAUSE (3981532373)
#define CMD_CANREINIT (2030075842)
#define CMD_CANRESUME (2051659720)
#define CMD_CANSEND (237136225)
#define CMD_CANSPEED (549265992)
#define CMD_CANSTAT (237384179)
#define CMD_DELIGNLIST (2235834164)
#define CMD_DIAGN (2334137736)
#define CMD_DUMPCMD (1223955823)
#define CMD_DUMPCONF (3271513185)
#define CMD_DUMPERR (1223989764)
#define CMD_EMSTOP (2965919005)
#define CMD_ENCPOS (3208428301)
#define CMD_ENCREV (3208460296)
#define CMD_ENCSTEPMAX (1022989757)
#define CMD_ENCSTEPMIN (1022990779)
#define CMD_ERASEFLASH (3177247267)
#define CMD_ESW (2963094612)
#define CMD_ESWREACT (1614224995)
#define CMD_GOTO (4286309438)
#define CMD_GOTOZ (3178103736)
#define CMD_GPIO (4286324660)
#define CMD_GPIOCONF (1309721562)
#define CMD_MAXSPEED (1498078812)
#define CMD_MAXSTEPS (1506667002)
#define CMD_MCUT (4022718)
#define CMD_MCUVDD (2517587080)
#define CMD_MICROSTEPS (3974395854)
#define CMD_MINSPEED (3234848090)
#define CMD_MOTFLAGS (2153634658)
#define CMD_MOTMUL (1543400099)
#define CMD_MOTREINIT (199682784)
#define CMD_PING (10561715)
#define CMD_RELPOS (1278646042)
#define CMD_RELSLOW (1742971917)
#define CMD_RESET (1907803304)
#define CMD_SAVECONF (141102426)
#define CMD_SCREEN (2100809349)
#define CMD_SPEEDLIMIT (1654184245)
#define CMD_STATE (2216628902)
#define CMD_STOP (17184971)
#define CMD_TIME (19148340)
#define CMD_TMCBUS (1906135955)
#define CMD_UDATA (2736127636)
#define CMD_USARTSTATUS (4007098968)

View File

@@ -0,0 +1,56 @@
"absposN* - GS absolute position (in steps, setter just changes current value)\n"
"accelN* - GS accel/decel (steps/s^2)\n"
"adcN* - G ADC value (N=0..3)\n"
"button[N]* - G all or given (N=0..6) buttons' state\n"
"canerrcodes - G print last CAN errcodes\n"
"canfilter - GS can filters, format: bank# FIFO# mode(M/I) num0 [num1 [num2 [num3]]]\n"
"canflood - send/clear flood message: ID byte0 ... byteN\n"
"canfloodT - GS flood period (>=0ms)\n"
"canid* - GS CAN ID of device\n"
"canignore - GS ignore list (max 10 IDs), negative to delete\n"
"canincrflood - send incremental flood message (ID is last for 'flood', stop by 'flood')\n"
"canpause - pause IN packets displaying\n"
"canreinit - reinit CAN\n"
"canresume - resume IN packets displaying\n"
"cansend - send data over CAN: send ID byte0 .. byteN (N<8)\n"
"canspeed - GS CAN speed (reinit if setter)\n"
"canstat - G CAN status\n"
"delignlist* - delete ignore list\n"
"diagn[N] - G DIAG state of motor N (or all)\n"
"dumperr* - dump error codes\n"
"dumpcmd* - dump command codes\n"
"dumpconf* - dump current configuration\n"
"emstop[N]* - emergency stop motor N or all\n"
"encposN* - GS encoder's position\n"
"encrevN* - GS max encoder's pulses per revolution\n"
"encstepmaxN* - GS maximal encoder ticks per step\n"
"encstepminN* - GS minimal encoder ticks per step\n"
"eraseflash* - erase flash data storage\n"
"esw[N]* - G end-switches state\n"
"eswreactN* - GS end-switches reaction (0 - ignore, 1 - stop@any, 2 - stop@zero)\n"
"gotoN* - GS move motor to given absolute position\n"
"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"
"maxspeedN* - GS max speed (steps per sec)\n"
"maxstepsN* - GS max steps (from zero ESW)\n"
"mcut* - G MCU T\n"
"mcuvdd* - G MCU Vdd\n"
"microstepsN* - GS microsteps settings (2^0..2^9)\n"
"minspeedN* - min speed (steps per sec)\n"
"motflagsN* - motorN flags\n"
"motmul* - GS external multiplexer status (<0 - disable, 0..7 - enable and set address)\n"
"motreinit* - re-init motors after configuration changed\n"
"ping* - echo given command back\n"
"relposN* - GS relative move (get remaining)\n"
"relslowN* - GS like 'relpos' but with slowest speed\n"
"reset* - software reset\n"
"saveconf* - save current configuration\n"
"screen* - GS screen enable (1) or disable (0)\n"
"speedlimit* - G limiting speed for current microsteps setting\n"
"stateN* - G motor state (0-relax, 1-accel, 2-move, 3-mvslow, 4-decel, 5-stall, 6-err)\n"
"stopN* - stop motor with deceleration\n"
"time* - G time from start (ms)\n"
"tmcbus* - GS TMC control bus (0 - USART, 1 - SPI)\n"
"udata - GS data by usart in slave mode (text strings, '\\n'-terminated)\n"
"usartstatus* - GS status of USART1 (0 - off, 1 - master, 2 - slave)\n"

View File

@@ -0,0 +1,4 @@
#!/bin/bash
awk '{print $1}' helpcmds.in |sed -e 's/"//' -e 's/\*//' -e 's/\[.*//' -e 's/N//' > testdic
./hashgen -d testdic -H hdr.h -S hdr.c -F

View File

@@ -0,0 +1,10 @@
#!/bin/bash
gcc hashgen.c -o hashgen -lusefull_macros
./hashgen -d testdic -H hdr.h -S hdr.c -F
gcc hdr.c test.c strfunc.c -o test
./test "time 54 = some"
./test "voltage12 more"
./test "esw45 = some text"
./test "goto 55 = "
./test "stop 3256"

View File

@@ -0,0 +1,256 @@
#include "strfunc.h"
/**
* @brief hexdump - dump hex array by 16 bytes in string
* @param sendfun - function to send data
* @param arr - array to dump
* @param len - length of `arr`
*/
void hexdump(int (*sendfun)(const char *s), uint8_t *arr, uint16_t len){
char buf[52], *bptr = buf;
for(uint16_t l = 0; l < len; ++l, ++arr){
for(int16_t j = 1; j > -1; --j){
register uint8_t half = (*arr >> (4*j)) & 0x0f;
if(half < 10) *bptr++ = half + '0';
else *bptr++ = half - 10 + 'a';
}
if(l % 16 == 15){
*bptr++ = '\n';
*bptr = 0;
sendfun(buf);
bptr = buf;
}else *bptr++ = ' ';
}
if(bptr != buf){
*bptr++ = '\n';
*bptr = 0;
sendfun(buf);
}
}
/**
* @brief _2str - convert value into string buffer
* @param val - |value|
* @param minus - ==0 if value > 0
* @return buffer with number
*/
static char *_2str(uint32_t val, uint8_t minus){
static char strbuf[12];
char *bufptr = &strbuf[11];
*bufptr = 0;
if(!val){
*(--bufptr) = '0';
}else{
while(val){
uint32_t x = val / 10;
*(--bufptr) = (val - 10*x) + '0';
val = x;
//*(--bufptr) = val % 10 + '0';
//val /= 10;
}
}
if(minus) *(--bufptr) = '-';
return bufptr;
}
// return string with number `val`
char *u2str(uint32_t val){
return _2str(val, 0);
}
char *i2str(int32_t i){
uint8_t minus = 0;
uint32_t val;
if(i < 0){
minus = 1;
val = -i;
}else val = i;
return _2str(val, minus);
}
/**
* @brief uhex2str - print 32bit unsigned int as hex
* @param val - value
* @return string with number
*/
char *uhex2str(uint32_t val){
static char buf[12] = "0x";
int npos = 2;
uint8_t *ptr = (uint8_t*)&val + 3;
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) buf[npos++] = half + '0';
else buf[npos++] = half - 10 + 'a';
}
}
buf[npos] = 0;
return buf;
}
/**
* @brief omit_spaces - eliminate leading spaces and other trash in string
* @param buf - string
* @return - pointer to first character in `buf` > ' '
*/
const char *omit_spaces(const char *buf){
while(*buf){
if(*buf > ' ') break;
++buf;
}
return buf;
}
/**
* @brief getdec - read decimal number & return pointer to next non-number symbol
* @param buf - string
* @param N - number read
* @return Next non-number symbol. In case of overflow return `buf` and N==0xffffffff
*/
static const char *getdec(const char *buf, uint32_t *N){
char *start = (char*)buf;
uint32_t num = 0;
while(*buf){
char c = *buf;
if(c < '0' || c > '9'){
break;
}
if(num > 429496729 || (num == 429496729 && c > '5')){ // overflow
*N = 0xffffff;
return start;
}
num *= 10;
num += c - '0';
++buf;
}
*N = num;
return buf;
}
// read hexadecimal number (without 0x prefix!)
static const char *gethex(const char *buf, uint32_t *N){
const char *start = buf;
uint32_t num = 0;
while(*buf){
char c = *buf;
uint8_t M = 0;
if(c >= '0' && c <= '9'){
M = '0';
}else if(c >= 'A' && c <= 'F'){
M = 'A' - 10;
}else if(c >= 'a' && c <= 'f'){
M = 'a' - 10;
}
if(M){
if(num & 0xf0000000){ // overflow
*N = 0xffffff;
return start;
}
num <<= 4;
num += c - M;
}else{
break;
}
++buf;
}
*N = num;
return buf;
}
// read octal number (without 0 prefix!)
static const char *getoct(const char *buf, uint32_t *N){
const char *start = (char*)buf;
uint32_t num = 0;
while(*buf){
char c = *buf;
if(c < '0' || c > '7'){
break;
}
if(num & 0xe0000000){ // overflow
*N = 0xffffff;
return start;
}
num <<= 3;
num += c - '0';
++buf;
}
*N = num;
return buf;
}
// read binary number (without b prefix!)
static const char *getbin(const char *buf, uint32_t *N){
const char *start = (char*)buf;
uint32_t num = 0;
while(*buf){
char c = *buf;
if(c < '0' || c > '1'){
break;
}
if(num & 0x80000000){ // overflow
*N = 0xffffff;
return start;
}
num <<= 1;
if(c == '1') num |= 1;
++buf;
}
*N = num;
return buf;
}
/**
* @brief getnum - read uint32_t from string (dec, hex or bin: 127, 0x7f, 0b1111111)
* @param buf - buffer with number and so on
* @param N - the number read
* @return pointer to first non-number symbol in buf
* (if it is == buf, there's no number or if *N==0xffffffff there was overflow)
*/
const char *getnum(const char *txt, uint32_t *N){
const char *nxt = NULL;
const char *s = omit_spaces(txt);
if(*s == '0'){ // hex, oct or 0
if(s[1] == 'x' || s[1] == 'X'){ // hex
nxt = gethex(s+2, N);
if(nxt == s+2) nxt = (char*)txt;
}else if(s[1] > '0'-1 && s[1] < '8'){ // oct
nxt = getoct(s+1, N);
if(nxt == s+1) nxt = (char*)txt;
}else{ // 0
nxt = s+1;
*N = 0;
}
}else if(*s == 'b' || *s == 'B'){
nxt = getbin(s+1, N);
if(nxt == s+1) nxt = (char*)txt;
}else{
nxt = getdec(s, N);
if(nxt == s) nxt = (char*)txt;
}
return nxt;
}
// get signed integer
const char *getint(const char *txt, int32_t *I){
const char *s = omit_spaces(txt);
int32_t sign = 1;
uint32_t U;
if(*s == '-'){
sign = -1;
++s;
}
const char *nxt = getnum(s, &U);
if(nxt == s) return txt;
if(U & 0x80000000) return txt; // overfull
*I = sign * (int32_t)U;
return nxt;
}
/*
void mymemcpy(char *dest, const char *src, int len){
if(len < 1) return;
while(len--) *dest++ = *src++;
}
*/

View File

@@ -0,0 +1,13 @@
#pragma once
#include <stdint.h>
#include <string.h>
void hexdump(int (*sendfun)(const char *s), uint8_t *arr, uint16_t len);
char *u2str(uint32_t val);
char *i2str(int32_t i);
char *uhex2str(uint32_t val);
const char *getnum(const char *txt, uint32_t *N);
const char *omit_spaces(const char *buf);
const char *getint(const char *txt, int32_t *I);
//void mymemcpy(char *dest, const char *src, int len);

View File

@@ -0,0 +1,62 @@
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "hdr.h"
#include "strfunc.h"
static int noargs(uint32_t hash){
switch(hash){
case CMD_REBOOT: printf("REBOOT\n"); break;
case CMD_TIME: printf("TIME!\n"); break;
case CMD_TEMP: printf("Temp\n"); break;
default: printf("Unknown hash 0x%x\n", hash); return 0;
}
return 1;
}
static int withparno(uint32_t hash, char *args){
uint32_t N;
//printf("args=%s\n", args);
const char *nxt = getnum((const char*)args, &N);
if(nxt == args){ printf("need arg\n"); return RET_WRONGCMD; }
args = (char*)omit_spaces(nxt);
if(*args){
if(*args != '='){ printf("need nothing or '=' after par\n"); return RET_WRONGCMD; }
args = (char*)omit_spaces(args+1);
// we can check in next functions what if `args` will be an empty string
}
else args = NULL;
const char *fname = NULL;
switch(hash){
case CMD_ESW: fname = "ESW"; break;
case CMD_GOTO: fname = "GOTO"; break;
case CMD_POS: fname = "POS"; break;
case CMD_STOP: fname = "STOP"; break;
default: fname = "unknown";
}
if(!args) printf("We want a getter '%s' with par %u\n", fname, N);
else printf("We want a setter '%s' with par %u and arg '%s'\n", fname, N, args);
if(N > 255){ printf("N should be 0..255\n"); return RET_BAD;}
return RET_GOOD;
}
// these functions should be global to substitute weak aliases
int fn_esw(uint32_t hash, char *args){return withparno(hash, args);}
int fn_goto(uint32_t hash, char *args){return withparno(hash, args);}
int fn_pos(uint32_t hash, char *args){return withparno(hash, args);}
int fn_stop(uint32_t hash, char *args){return withparno(hash, args);}
int fn_voltage(uint32_t hash, char *args){return withparno(hash, args);}
int fn_reboot(uint32_t hash, _U_ char *args){return noargs(hash);}
int fn_time(uint32_t hash, _U_ char *args){return noargs(hash);}
int fn_temp(uint32_t hash, _U_ char *args){return noargs(hash);}
int main(int argc, char **argv){
if(argc != 2) return 1;
int ret = parsecmd(argv[1]);
switch(ret){
case RET_CMDNOTFOUND: printf("'%s' not found\n", argv[1]); break;
case RET_WRONGCMD: printf("Wrong sintax of '%s'\n", argv[1]); break;
case RET_GOOD: printf("'%s' - OK\n", argv[1]); break;
default: printf("'%s' - bad\n", argv[1]);
}
return 0;
}

View File

@@ -0,0 +1,56 @@
abspos
accel
adc
button
canerrcodes
canfilter
canflood
canfloodT
canid
canignore
canincrflood
canpause
canreinit
canresume
cansend
canspeed
canstat
delignlist
diagn
dumperr
dumpcmd
dumpconf
emstop
encpos
encrev
encstepmax
encstepmin
eraseflash
esw
eswreact
goto
gotoz
gpioconf
gpio
maxspeed
maxsteps
mcut
mcuvdd
microsteps
minspeed
motflags
motmul
motreinit
ping
relpos
relslow
reset
saveconf
screen
speedlimit
state
stop
time
tmcbus
udata
usartstatus