diff --git a/F0-nolib/3steppersLB/can.c b/F0-nolib/3steppersLB/can.c index d17e9cf..d506da3 100644 --- a/F0-nolib/3steppersLB/can.c +++ b/F0-nolib/3steppersLB/can.c @@ -338,7 +338,7 @@ TRUE_INLINE void parseCANcommand(CAN_message *msg){ formerr(msg, ERR_WRONGLEN); goto sendmessage; } - errcodes ec = cmdlist[Index].function(par, val); + errcodes ec = cmdlist[Index](par, val); if(ec != ERR_OK){ formerr(msg, ec); } diff --git a/F0-nolib/3steppersLB/commonproto.c b/F0-nolib/3steppersLB/commonproto.c index bd8a57e..4793f2a 100644 --- a/F0-nolib/3steppersLB/commonproto.c +++ b/F0-nolib/3steppersLB/commonproto.c @@ -76,6 +76,7 @@ static errcodes eswparser(uint8_t par, int32_t *val){ #endif uint8_t n = PARBASE(par); if(n > ESWNO-1){ // all + *val = 0; uint8_t *arr = (uint8_t*)val; for(int i = 0; i < ESWNO; ++i) *arr++ = ESW_state(i); @@ -283,6 +284,19 @@ static errcodes motflagsparser(uint8_t par, int32_t *val){ return ERR_OK; } +// setter of GLOBAL reaction, getter of LOCAL! +static errcodes eswreactparser(uint8_t par, int32_t *val){ + uint8_t n = PARBASE(par); + if(n > MOTORSNO-1) return ERR_BADPAR; + if(ISSETTER(par)){ + if(*val < 0 || *val > ESW_AMOUNT-1) return ERR_BADVAL; + the_conf.ESW_reaction[n] = *val; + } + // *val = the_conf.ESW_reaction[n]; + *val = geteswreact(n); + return ERR_OK; +} + static errcodes saveconfparser(uint8_t _U_ par, int32_t _U_ *val){ if(store_userconf()) return ERR_CANTRUN; return ERR_OK; @@ -296,7 +310,20 @@ static errcodes reinitmparser(uint8_t _U_ par, int32_t _U_ *val){ return ERR_OK; } -static errcodes mstopparser(uint8_t par, int32_t _U_ *val){ +static errcodes emstopparser(uint8_t par, int32_t _U_ *val){ + uint8_t n = PARBASE(par); + if(n > MOTORSNO-1) return ERR_BADPAR; + emstopmotor(n); + return ERR_OK; +} + +static errcodes emstopallparser(uint8_t _U_ par, int32_t _U_ *val){ + for(int i = 0; i < MOTORSNO; ++i) + emstopmotor(i); + return ERR_OK; +} + +static errcodes stopparser(uint8_t par, int32_t _U_ *val){ uint8_t n = PARBASE(par); if(n > MOTORSNO-1) return ERR_BADPAR; stopmotor(n); @@ -317,6 +344,13 @@ static errcodes relstepsparser(uint8_t par, int32_t *val){ return getremainsteps(n, val); } +static errcodes relslowparser(uint8_t par, int32_t *val){ + uint8_t n = PARBASE(par); + if(n > MOTORSNO-1) return ERR_BADPAR; + if(ISSETTER(par)) return motor_relslow(n, *val); + return getremainsteps(n, val); +} + static errcodes motstateparser(uint8_t par, int32_t *val){ uint8_t n = PARBASE(par); if(n > MOTORSNO-1) return ERR_BADPAR; @@ -334,6 +368,12 @@ static errcodes encposparser(uint8_t par, int32_t *val){ *val = encoder_position(n); return ret; } + +static errcodes gotozeroparser(uint8_t par, _U_ int32_t *val){ + uint8_t n = PARBASE(par); + if(n > MOTORSNO-1) return ERR_BADPAR; + return motor_goto0(n); +} /******************* END of motors' parsers *******************/ /* @@ -342,39 +382,44 @@ static errcodes parser(uint8_t _U_ par, int32_t _U_ *val){ } */ -// the main commands list, index is CAN command code -const commands cmdlist[CMD_AMOUNT] = { +const fpointer cmdlist[CMD_AMOUNT] = { // different commands - [CMD_PING] = {"ping", pingparser, "echo given command back"}, - [CMD_RELAY] = {"relay", relayparser, "change relay state (1/0)"}, - [CMD_BUZZER] = {"buzzer", buzzerparser, "change buzzer state (1/0)"}, - [CMD_ADC] = {"adc", adcparser, "get ADC values"}, - [CMD_BUTTONS] = {"button", buttonsparser, "get buttons state"}, - [CMD_ESWSTATE] = {"esw", eswparser, "get end switches state"}, - [CMD_MCUT] = {"mcut", mcutparser, "get MCU T"}, - [CMD_MCUVDD] = {"mcuvdd", mcuvddparser, "get MCU Vdd"}, - [CMD_RESET] = {"reset", resetparser, "reset MCU"}, - [CMD_TIMEFROMSTART] = {"time", timeparser, "get time from start"}, - [CMD_PWM] = {"pwm", pwmparser, "pwm value"}, - [CMD_EXT] = {"ext", extparser, "external outputs"}, + [CMD_PING] = pingparser, + [CMD_RELAY] = relayparser, + [CMD_BUZZER] = buzzerparser, + [CMD_ADC] = adcparser, + [CMD_BUTTONS] = buttonsparser, + [CMD_ESWSTATE] = eswparser, + [CMD_MCUT] = mcutparser, + [CMD_MCUVDD] = mcuvddparser, + [CMD_RESET] = resetparser, + [CMD_TIMEFROMSTART] = timeparser, + [CMD_PWM] = pwmparser, + [CMD_EXT] = extparser, // configuration - [CMD_SAVECONF] = {"saveconf", saveconfparser, "save current configuration"}, - [CMD_ENCSTEPMIN] = {"encstepmin", encstepsminparser, "minimal encoder ticks per step"}, - [CMD_ENCSTEPMAX] = {"encstepmax", encstepsmaxparser, "maximal encoder ticks per step"}, - [CMD_MICROSTEPS] = {"microsteps", ustepsparser, "set/get microsteps settings"}, - [CMD_ACCEL] = {"accel", accparser, "set/get accel/decel (steps/s^2)"}, - [CMD_MAXSPEED] = {"maxspeed", maxspdparser, "set/get max speed (steps per sec)"}, - [CMD_MINSPEED] = {"minspeed", minspdparser, "set/get min speed (steps per sec)"}, - [CMD_SPEEDLIMIT] = {"speedlimit", spdlimparser, "get limiting speed for current microsteps"}, - [CMD_MAXSTEPS] = {"maxsteps", maxstepsparser, "set/get max steps (from zero)"}, - [CMD_ENCREV] = {"encrev", encrevparser, "set/get max encoder's pulses per revolution"}, - [CMD_MOTFLAGS] = {"motflags", motflagsparser, "set/get motorN flags"}, + [CMD_SAVECONF] = saveconfparser, + [CMD_ENCSTEPMIN] = encstepsminparser, + [CMD_ENCSTEPMAX] = encstepsmaxparser, + [CMD_MICROSTEPS] = ustepsparser, + [CMD_ACCEL] = accparser, + [CMD_MAXSPEED] = maxspdparser, + [CMD_MINSPEED] = minspdparser, + [CMD_SPEEDLIMIT] = spdlimparser, + [CMD_MAXSTEPS] = maxstepsparser, + [CMD_ENCREV] = encrevparser, + [CMD_MOTFLAGS] = motflagsparser, + [CMD_ESWREACT] = eswreactparser, // motor's commands - [CMD_ABSPOS] = {"abspos", curposparser, "set/get position (in steps)"}, - [CMD_RELPOS] = {"relpos", relstepsparser, "set relative steps, get remaining"}, - [CMD_STOPMOTOR] = {"stop", mstopparser, "stop motor now"}, - [CMD_REINITMOTORS] = {"motreinit", reinitmparser, "re-init motors after configuration changed"}, - [CMD_MOTORSTATE] = {"state", motstateparser, "get motor state"}, - [CMD_ENCPOS] = {"encpos", encposparser, "set/get encoder's position"}, + [CMD_ABSPOS] = curposparser, + [CMD_RELPOS] = relstepsparser, + [CMD_RELSLOW] = relslowparser, + [CMD_EMERGSTOP] = emstopparser, + [CMD_EMERGSTOPALL] = emstopallparser, + [CMD_STOP] = stopparser, + [CMD_REINITMOTORS] = reinitmparser, + [CMD_MOTORSTATE] = motstateparser, + [CMD_ENCPOS] = encposparser, + [CMD_GOTOZERO] = gotozeroparser, }; + diff --git a/F0-nolib/3steppersLB/commonproto.h b/F0-nolib/3steppersLB/commonproto.h index 524f252..efb5756 100644 --- a/F0-nolib/3steppersLB/commonproto.h +++ b/F0-nolib/3steppersLB/commonproto.h @@ -51,12 +51,6 @@ typedef enum{ // @return CANERR_OK (0) if OK or error code typedef errcodes (*fpointer)(uint8_t par, int32_t *val); -typedef struct{ - const char *command; // text command (up to 65536 commands) - fpointer function; // function to execute: function(&par, &val) - const char *help; // help message for text protocol -} commands; - enum{ CMD_PING // ping device ,CMD_RELAY // relay on/off @@ -81,21 +75,23 @@ enum{ ,CMD_MAXSTEPS // max steps (-max..+max) ,CMD_ENCREV // encoder's pulses per revolution ,CMD_MOTFLAGS // motor flags + ,CMD_ESWREACT // ESW reaction flags ,CMD_REINITMOTORS // re-init motors after configuration changing ,CMD_ABSPOS // current position (set/get) ,CMD_RELPOS // set relative steps or get steps left - ,CMD_STOPMOTOR // stop moving NOW + ,CMD_RELSLOW // change relative position at lowest speed + ,CMD_EMERGSTOP // stop moving NOW + ,CMD_STOP // smooth motor stop + ,CMD_EMERGSTOPALL // emergency stop for all motors + ,CMD_GOTOZERO // go to zero's ESW ,CMD_MOTORSTATE // motor state ,CMD_ENCPOS // position of encoder (independing on settings) //,CMD_STOPDECEL - //,CMD_RELMOVE - //,CMD_ABSMOVE - //,CMD_MOVE // @max speed infty //,CMD_FINDZERO // should be the last: ,CMD_AMOUNT // amount of common commands }; -extern const commands cmdlist[CMD_AMOUNT]; +extern const fpointer cmdlist[CMD_AMOUNT]; #endif // COMMONPROTO_H__ diff --git a/F0-nolib/3steppersLB/flash.c b/F0-nolib/3steppersLB/flash.c index b9ff680..84de13b 100644 --- a/F0-nolib/3steppersLB/flash.c +++ b/F0-nolib/3steppersLB/flash.c @@ -49,7 +49,7 @@ static uint32_t maxCnum = 1024 / sizeof(user_conf); // can't use blocksize here ,.encperstepmin = {17,17,17} \ ,.encperstepmax = {23,23,23} \ ,.motflags = {DEFMF,DEFMF,DEFMF} \ - ,.ESW_reaction = {ESW_ANYSTOP, ESW_ANYSTOP, ESW_ANYSTOP} \ + ,.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); @@ -217,8 +217,6 @@ void dump_userconf(_U_ char *txt){ for(int i = 0; i < MOTORSNO; ++i){ char cur = '0' + i; #define PROPNAME(nm) do{newline(); SEND(nm); bufputchar(cur); bufputchar('=');}while(0) - PROPNAME("reverse"); - bufputchar('0' + the_conf.motflags[i].reverse); PROPNAME("microsteps"); printu(the_conf.microsteps[i]); PROPNAME("accel"); diff --git a/F0-nolib/3steppersLB/flash.h b/F0-nolib/3steppersLB/flash.h index 7eccc72..a557426 100644 --- a/F0-nolib/3steppersLB/flash.h +++ b/F0-nolib/3steppersLB/flash.h @@ -39,7 +39,7 @@ // register with flash size (in blocks) #ifndef FLASH_SIZE_REG -blocksizeASH_SIZE_REG ((uint32_t)0x1FFFF7CC) +#define FLASH_SIZE_REG ((uint32_t)0x1FFFF7CC) #endif #define FLASH_SIZE *((uint16_t*)FLASH_SIZE_REG) diff --git a/F0-nolib/3steppersLB/hardware.c b/F0-nolib/3steppersLB/hardware.c index 91c19e5..a27179e 100644 --- a/F0-nolib/3steppersLB/hardware.c +++ b/F0-nolib/3steppersLB/hardware.c @@ -87,7 +87,7 @@ static IRQn_Type motirqs[MOTORSNO] = {TIM15_IRQn, TIM14_IRQn, TIM16_IRQn}; static void setup_mpwm(int i){ volatile TIM_TypeDef *TIM = mottimers[i]; TIM->CR1 = TIM_CR1_ARPE; // buffered ARR - TIM->PSC = MOTORTIM_PSC; // 64kHz + TIM->PSC = MOTORTIM_PSC; // 16MHz // PWM mode 1 (active -> inactive) TIM->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1; #if MOTORTIM_ARRMIN < 5 diff --git a/F0-nolib/3steppersLB/proto.c b/F0-nolib/3steppersLB/proto.c deleted file mode 100644 index 9803e51..0000000 --- a/F0-nolib/3steppersLB/proto.c +++ /dev/null @@ -1,626 +0,0 @@ -/* - * This file is part of the canrelay project. - * Copyright 2021 Edward V. Emelianov . - * - * 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 . - */ - -#include "adc.h" -#include "buttons.h" -#include "can.h" -#include "hardware.h" -#include "proto.h" -#include "usb.h" - -#include // strlen - -extern volatile uint8_t canerror; - -uint8_t ShowMsgs = 0; -uint16_t Ignore_IDs[IGN_SIZE]; -uint8_t IgnSz = 0; -static char buff[BUFSZ+1], *bptr = buff; -static uint8_t blen = 0; - -void sendbuf(){ - IWDG->KR = IWDG_REFRESH; - if(blen == 0) return; - *bptr = 0; - USB_sendstr(buff); - bptr = buff; - blen = 0; -} - -void bufputchar(char ch){ - if(blen > BUFSZ-1){ - sendbuf(); - } - *bptr++ = ch; - ++blen; -} - -void addtobuf(const char *txt){ - IWDG->KR = IWDG_REFRESH; - while(*txt) bufputchar(*txt++); -} - -char *omit_spaces(const char *buf){ - while(*buf){ - if(*buf > ' ') break; - ++buf; - } - return (char*) buf; -} - -// THERE'S NO OVERFLOW PROTECTION IN NUMBER READ PROCEDURES! -// read decimal number -static char *getdec(const char *buf, uint32_t *N){ - uint32_t num = 0; - while(*buf){ - char c = *buf; - if(c < '0' || c > '9'){ - break; - } - num *= 10; - num += c - '0'; - ++buf; - } - *N = num; - return (char *)buf; -} -// read hexadecimal number (without 0x prefix!) -static char *gethex(const char *buf, uint32_t *N){ - 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){ - num <<= 4; - num += c - M; - }else{ - break; - } - ++buf; - } - *N = num; - return (char *)buf; -} -// read binary number (without 0b prefix!) -static char *getbin(const char *buf, uint32_t *N){ - uint32_t num = 0; - while(*buf){ - char c = *buf; - if(c < '0' || c > '1'){ - break; - } - num <<= 1; - if(c == '1') num |= 1; - ++buf; - } - *N = num; - return (char *)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) - */ -char *getnum(const char *txt, uint32_t *N){ - if(*txt == '0'){ - if(txt[1] == 'x' || txt[1] == 'X') return gethex(txt+2, N); - if(txt[1] == 'b' || txt[1] == 'B') return getbin(txt+2, N); - } - return getdec(txt, N); -} - -// parse `txt` to CAN_message -static CAN_message *parseCANmsg(char *txt){ - static CAN_message canmsg; - //SEND("CAN command with arguments:\n"); - uint32_t N; - char *n; - int ctr = -1; - canmsg.ID = 0xffff; - do{ - txt = omit_spaces(txt); - n = getnum(txt, &N); - if(txt == n) break; - txt = n; - if(ctr == -1){ - if(N > 0x7ff){ - SEND("ID should be 11-bit number!\n"); - return NULL; - } - canmsg.ID = (uint16_t)(N&0x7ff); - //SEND("ID="); printuhex(canmsg.ID); newline(); - ctr = 0; - continue; - } - if(ctr > 7){ - SEND("ONLY 8 data bytes allowed!\n"); - return NULL; - } - if(N > 0xff){ - SEND("Every data portion is a byte!\n"); - return NULL; - } - canmsg.data[ctr++] = (uint8_t)(N&0xff); - }while(1); - if(canmsg.ID == 0xffff){ - SEND("NO ID given, send nothing!\n"); - return NULL; - } - SEND("Message parsed OK\n"); - sendbuf(); - canmsg.length = (uint8_t) ctr; - return &canmsg; -} - -// send command, format: ID (hex/bin/dec) data bytes (up to 8 bytes, space-delimeted) -TRUE_INLINE void sendCANcommand(char *txt){ - CAN_message *msg = parseCANmsg(txt); - if(!msg) return; - uint32_t N = 1000; - while(CAN_BUSY == can_send(msg->data, msg->length, msg->ID)){ - if(--N == 0) break; - } -} - -TRUE_INLINE void CANini(char *txt){ - txt = omit_spaces(txt); - uint32_t N; - char *n = getnum(txt, &N); - if(txt == n){ - SEND("No speed given"); - return; - } - if(N < 50){ - SEND("Lowest speed is 50kbps"); - return; - }else if(N > 3000){ - SEND("Highest speed is 3000kbps"); - return; - } - CAN_reinit((uint16_t)N); - SEND("Reinit CAN bus with speed "); - printu(N); SEND("kbps"); -} - -TRUE_INLINE void addIGN(char *txt){ - if(IgnSz == IGN_SIZE){ - MSG("Ignore buffer is full"); - return; - } - txt = omit_spaces(txt); - uint32_t N; - char *n = getnum(txt, &N); - if(txt == n){ - SEND("No ID given"); - return; - } - if(N == CANID){ - SEND("You can't ignore self ID!"); - return; - } - if(N > 0x7ff){ - SEND("ID should be 11-bit number!"); - return; - } - Ignore_IDs[IgnSz++] = (uint16_t)(N & 0x7ff); - SEND("Added ID "); printu(N); - SEND("\nIgn buffer size: "); printu(IgnSz); -} - -TRUE_INLINE void print_ign_buf(){ - if(IgnSz == 0){ - SEND("Ignore buffer is empty"); - return; - } - SEND("Ignored IDs:\n"); - for(int i = 0; i < IgnSz; ++i){ - printu(i); - SEND(": "); - printuhex(Ignore_IDs[i]); - newline(); - } -} - -// print ID/mask of CAN->sFilterRegister[x] half -static void printID(uint16_t FRn){ - if(FRn & 0x1f) return; // trash - printuhex(FRn >> 5); -} -/* -Can filtering: FSCx=0 (CAN->FS1R) -> 16-bit identifiers -CAN->FMR = (sb)<<8 | FINIT - init filter in starting bank sb -CAN->FFA1R FFAx = 1 -> FIFO1, 0 -> FIFO0 -CAN->FA1R FACTx=1 - filter active -MASK: FBMx=0 (CAN->FM1R), two filters (n in FR1 and n+1 in FR2) - ID: CAN->sFilterRegister[x].FRn[0..15] - MASK: CAN->sFilterRegister[x].FRn[16..31] - FR bits: STID[10:0] RTR IDE EXID[17:15] -LIST: FBMx=1, four filters (n&n+1 in FR1, n+2&n+3 in FR2) - IDn: CAN->sFilterRegister[x].FRn[0..15] - IDn+1: CAN->sFilterRegister[x].FRn[16..31] -*/ -TRUE_INLINE void list_filters(){ - uint32_t fa = CAN->FA1R, ctr = 0, mask = 1; - while(fa){ - if(fa & 1){ - SEND("Filter "); printu(ctr); SEND(", FIFO"); - if(CAN->FFA1R & mask) SEND("1"); - else SEND("0"); - SEND(" in "); - if(CAN->FM1R & mask){ // up to 4 filters in LIST mode - SEND("LIST mode, IDs: "); - printID(CAN->sFilterRegister[ctr].FR1 & 0xffff); - SEND(" "); - printID(CAN->sFilterRegister[ctr].FR1 >> 16); - SEND(" "); - printID(CAN->sFilterRegister[ctr].FR2 & 0xffff); - SEND(" "); - printID(CAN->sFilterRegister[ctr].FR2 >> 16); - }else{ // up to 2 filters in MASK mode - SEND("MASK mode: "); - if(!(CAN->sFilterRegister[ctr].FR1&0x1f)){ - SEND("ID="); printID(CAN->sFilterRegister[ctr].FR1 & 0xffff); - SEND(", MASK="); printID(CAN->sFilterRegister[ctr].FR1 >> 16); - SEND(" "); - } - if(!(CAN->sFilterRegister[ctr].FR2&0x1f)){ - SEND("ID="); printID(CAN->sFilterRegister[ctr].FR2 & 0xffff); - SEND(", MASK="); printID(CAN->sFilterRegister[ctr].FR2 >> 16); - } - } - newline(); - } - fa >>= 1; - ++ctr; - mask <<= 1; - } - sendbuf(); -} - -/** - * @brief add_filter - add/modify filter - * @param str - string in format "bank# FIFO# mode num0 .. num3" - * where bank# - 0..27 - * if there's nothing after bank# - delete filter - * FIFO# - 0,1 - * mode - 'I' for ID, 'M' for mask - * num0..num3 - IDs in ID mode, ID/MASK for mask mode - */ -static void add_filter(char *str){ - uint32_t N; - str = omit_spaces(str); - char *n = getnum(str, &N); - if(n == str){ - SEND("No bank# given"); - return; - } - if(N == 0 || N > STM32F0FBANKNO-1){ - SEND("0 (reserved for self) < bank# < 28 (max bank# is 27)!!!"); - return; - } - uint8_t bankno = (uint8_t)N; - str = omit_spaces(n); - if(!*str){ // deactivate filter - SEND("Deactivate filters in bank "); - printu(bankno); - CAN->FMR = CAN_FMR_FINIT; - CAN->FA1R &= ~(1<FMR &=~ CAN_FMR_FINIT; - return; - } - uint8_t fifono = 0; - if(*str == '1') fifono = 1; - else if(*str != '0'){ - SEND("FIFO# is 0 or 1"); - return; - } - str = omit_spaces(str + 1); - char c = *str; - uint8_t mode = 0; // ID - if(c == 'M' || c == 'm') mode = 1; - else if(c != 'I' && c != 'i'){ - SEND("mode is 'M/m' for MASK and 'I/i' for IDLIST"); - return; - } - str = omit_spaces(str + 1); - uint32_t filters[4]; - uint32_t nfilt; - for(nfilt = 0; nfilt < 4; ++nfilt){ - n = getnum(str, &N); - if(n == str) break; - filters[nfilt] = N; - str = omit_spaces(n); - } - if(nfilt == 0){ - SEND("You should add at least one filter!"); - return; - } - if(mode && (nfilt&1)){ - SEND("In MASK mode you should point pairs of ID/MASK"); - return; - } - CAN->FMR = CAN_FMR_FINIT; - uint32_t mask = 1<FA1R |= mask; // activate given filter - if(fifono) CAN->FFA1R |= mask; // set FIFO number - else CAN->FFA1R &= ~mask; - if(mode) CAN->FM1R &= ~mask; // MASK - else CAN->FM1R |= mask; // LIST - uint32_t F1 = (0x8f<<16); - uint32_t F2 = (0x8f<<16); - // reset filter registers to wrong value - CAN->sFilterRegister[bankno].FR1 = (0x8f<<16) | 0x8f; - CAN->sFilterRegister[bankno].FR2 = (0x8f<<16) | 0x8f; - switch(nfilt){ - case 4: - F2 = filters[3] << 21; - // fallthrough - case 3: - CAN->sFilterRegister[bankno].FR2 = (F2 & 0xffff0000) | (filters[2] << 5); - // fallthrough - case 2: - F1 = filters[1] << 21; - // fallthrough - case 1: - CAN->sFilterRegister[bankno].FR1 = (F1 & 0xffff0000) | (filters[0] << 5); - } - CAN->FMR &=~ CAN_FMR_FINIT; - SEND("Added filter with "); - printu(nfilt); SEND(" parameters"); -} - -// print current buttons state -TRUE_INLINE void getBtnState(){ - const char *states[] = {[EVT_NONE] = NULL, [EVT_PRESS] = "pressed", [EVT_HOLD] = "holded", [EVT_RELEASE] = "released"}; - for(int i = 0; i < BTNSNO; ++i){ - uint32_t T; - keyevent e = keystate(i, &T); - if(e != EVT_NONE){ - SEND("The key "); printu(i); - SEND(" is "); addtobuf(states[e]); SEND(" at "); - printu(T); NL(); - } - } -} - -TRUE_INLINE void getPWM(){ - volatile uint32_t *reg = &TIM1->CCR1; - for(int n = 0; n < 3; ++n){ - SEND("PWM"); - bufputchar('0' + n); - bufputchar('='); - printu(*reg++); - bufputchar('\n'); - } - sendbuf(); -} - -TRUE_INLINE void changePWM(char *str){ - str = omit_spaces(str); - uint32_t N, pwm; - char *nxt = getnum(str, &N); - if(nxt == str || N > 2){ - SEND("Nch = 0..2"); - return; - } - str = omit_spaces(nxt); - nxt = getnum(str, &pwm); - if(nxt == str || pwm > 255){ - SEND("PWM should be from 0 to 255"); - return; - } - volatile uint32_t *reg = &TIM1->CCR1; - reg[N] = pwm; - SEND("OK, changed"); -} - -TRUE_INLINE void printADC(){ // show all 4 channels ADC - for(int i = 0; i < NUMBER_OF_ADC_CHANNELS; ++i){ - SEND("ADC"); bufputchar('0' + i); bufputchar('='); - printu(getADCval(i)); bufputchar('\n'); - } - sendbuf(); -} - -TRUE_INLINE void printVT(){ // show T and Vdd - int32_t t = getMCUtemp(); - SEND("T="); - if(t < 0){ bufputchar('-'); t = -t; } - printu(t); SEND("/10degC\nVDD="); - printu(getVdd()); SEND("/100V"); -} - -// set or check relay state -TRUE_INLINE void relay(const char *txt){ - txt = omit_spaces(txt); - uint32_t sr; - char *b = getnum(txt, &sr); - if(b && b != txt && sr < 2){ - if(sr) Relay_ON(); else Relay_OFF(); - } - SEND("Relay"); bufputchar('='); - bufputchar('0' + Relay_chk()); -} - -/** - * @brief cmd_parser - command parsing - * @param txt - buffer with commands & data - * @param isUSB - == 1 if data got from USB - */ -void cmd_parser(char *txt){ - char _1st = txt[0]; - /* - * parse long commands here - */ - switch(_1st){ - case '0': - relay(txt + 1); - goto eof; - break; - case 'a': - addIGN(txt + 1); - goto eof; - break; - case 'C': - CANini(txt + 1); - goto eof; - break; - case 'f': - add_filter(txt + 1); - goto eof; - break; - case 'F': - set_flood(parseCANmsg(txt + 1)); - goto eof; - break; - case 's': - case 'S': - sendCANcommand(txt + 1); - goto eof; - break; - case 'W': - changePWM(txt + 1); - goto eof; - break; - } - if(txt[1] != '\n') *txt = '?'; // help for wrong message length - switch(_1st){ - case 'A': - printADC(); - return; - break; - case 'b': - getBtnState(); - break; - case 'd': - IgnSz = 0; - break; - case 'D': - SEND("Go into DFU mode\n"); - sendbuf(); - Jump2Boot(); - break; - case 'I': - SEND("CAN ID: "); printuhex(CANID); - break; - case 'l': - list_filters(); - break; - case 'm': - printVT(); - break; - case 'p': - print_ign_buf(); - break; - case 'P': - ShowMsgs = !ShowMsgs; - if(ShowMsgs) SEND("Resume\n"); - else SEND("Pause\n"); - break; - case 'R': - SEND("Soft reset\n"); - sendbuf(); - pause_ms(5); // a little pause to transmit data - NVIC_SystemReset(); - break; - case 'T': - SEND("Time (ms): "); - printu(Tms); - break; - case 'w': - getPWM(); - return; - break; - default: // help - SEND( - "'0' - turn relay on(1) or off(0)\n" - "'a' - add ID to ignore list (max 10 IDs)\n" - "'A' - get ADC values @ all 4 channels\n" - "'b' - get buttons' state\n" - "'C' - reinit CAN with given baudrate\n" - "'d' - delete ignore list\n" - "'D' - activate DFU mode\n" - "'f' - add/delete filter, format: bank# FIFO# mode(M/I) num0 [num1 [num2 [num3]]]\n" - "'F' - send/clear flood message: F ID byte0 ... byteN\n" - "'I' - read CAN ID\n" - "'l' - list all active filters\n" - "'m' - get MCU temp & Vdd\n" - "'p' - print ignore buffer\n" - "'P' - pause/resume in packets displaying\n" - "'R' - software reset\n" - "'s/S' - send data over CAN: s ID byte0 .. byteN\n" - "'T' - get time from start (ms)\n" - "'w' - get PWM settings\n" - "'W' - set PWM @nth channel (ch: 0..2, PWM: 0..255)\n" - ); - break; - } -eof: - newline(); - sendbuf(); -} - -// print 32bit unsigned int -void printu(uint32_t val){ - char buf[11], *bufptr = &buf[10]; - *bufptr = 0; - if(!val){ - *(--bufptr) = '0'; - }else{ - while(val){ - *(--bufptr) = val % 10 + '0'; - val /= 10; - } - } - addtobuf(bufptr); -} - -// print 32bit unsigned int as hex -void printuhex(uint32_t val){ - addtobuf("0x"); - 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) bufputchar(half + '0'); - else bufputchar(half - 10 + 'a'); - } - } -} - -// check Ignore_IDs & return 1 if ID isn't in list -uint8_t isgood(uint16_t ID){ - for(int i = 0; i < IgnSz; ++i) - if(Ignore_IDs[i] == ID) return 0; - return 1; -} diff --git a/F0-nolib/3steppersLB/proto.h b/F0-nolib/3steppersLB/proto.h deleted file mode 100644 index 57d99b0..0000000 --- a/F0-nolib/3steppersLB/proto.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of the canrelay project. - * Copyright 2021 Edward V. Emelianov . - * - * 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 . - */ -#pragma once -#ifndef __PROTO_H__ -#define __PROTO_H__ - -#include "stm32f0.h" -#include "hardware.h" - -#define BUFSZ (64) - -// macro for static strings -#define SEND(str) do{addtobuf(str);}while(0) - -#ifdef EBUG -#define MSG(str) do{addtobuf(__FILE__ " (L" STR(__LINE__) "): " str);}while(0) -#else -#define MSG(str) -#endif - -#define newline() do{bufputchar('\n');}while(0) -// newline with buffer sending over USART -#define NL() do{bufputchar('\n'); sendbuf();}while(0) - -#define IGN_SIZE 10 -extern uint16_t Ignore_IDs[IGN_SIZE]; -extern uint8_t IgnSz; -extern uint8_t ShowMsgs; - -void cmd_parser(char *buf); -void addtobuf(const char *txt); -void bufputchar(char ch); -void printu(uint32_t val); -void printuhex(uint32_t val); -void sendbuf(); - -char *omit_spaces(const char *buf); -char *getnum(const char *buf, uint32_t *N); - -uint8_t isgood(uint16_t ID); - -#endif // __PROTO_H__ diff --git a/F0-nolib/3steppersLB/steppers.bin b/F0-nolib/3steppersLB/steppers.bin index a22fdee..b5dbaae 100755 Binary files a/F0-nolib/3steppersLB/steppers.bin and b/F0-nolib/3steppersLB/steppers.bin differ diff --git a/F0-nolib/3steppersLB/steppers.c b/F0-nolib/3steppersLB/steppers.c index c765262..4f8b211 100644 --- a/F0-nolib/3steppersLB/steppers.c +++ b/F0-nolib/3steppersLB/steppers.c @@ -23,10 +23,9 @@ // goto zero stages typedef enum{ - M0RELAX, // normal moving - M0FAST, // fast move to zero - M0PLUS, // move 200 steps + - M0SLOW // slowest move to zero + M0RELAX, // normal moving + M0FAST, // fast move to zero + M0SLOW // slowest move from ESW } mvto0state; typedef enum{ @@ -35,6 +34,8 @@ typedef enum{ STALL_STOP // Nstalled >= limit } t_stalled; +static t_stalled stallflags[MOTORSNO]; + // motors' direction: 1 for positive, -1 for negative (we need it as could be reverse) static int8_t motdir[MOTORSNO]; // current position (in steps) by STP counter @@ -51,6 +52,8 @@ static volatile int32_t encpos[MOTORSNO] = {0}; static int32_t prevencpos[MOTORSNO] = {0}; // encoders' ticks per step (calculates @ init) static int32_t encperstep[MOTORSNO]; +// ESW reaction - local copy +static uint8_t ESW_reaction[MOTORSNO]; // current speed static uint16_t curspeed[MOTORSNO]; @@ -62,7 +65,7 @@ static stp_state state[MOTORSNO]; // move to zero state static mvto0state mvzerostate[MOTORSNO]; -static uint8_t Nstalled = 0; // counter of STALL +static int8_t Nstalled[MOTORSNO] = {0}; // counter of STALL // lowest ARR value (highest speed), highest (lowest speed) //static uint16_t stphighARR[MOTORSNO]; @@ -97,6 +100,7 @@ void init_steppers(){ encperstep[i] = the_conf.encrev[i] / STEPSPERREV; if(!the_conf.motflags[i].donthold) MOTOR_EN(i); else MOTOR_DIS(i); + ESW_reaction[i] = the_conf.ESW_reaction[i]; } } @@ -161,7 +165,7 @@ static void calcacceleration(uint8_t i){ if(the_conf.motflags[i].reverse) MOTOR_CW(i); else MOTOR_CCW(i); } - state[i] = STP_ACCEL; + if(state[i] != STP_MVSLOW) state[i] = STP_ACCEL; startspeed[i] = curspeed[i]; Taccel[i] = Tms; recalcARR(i); @@ -170,10 +174,18 @@ static void calcacceleration(uint8_t i){ // move to absolute position errcodes motor_absmove(uint8_t i, int32_t newpos){ //if(i >= MOTORSNO) return ERR_BADPAR; // bad motor number - if(state[i] != STP_RELAX) return ERR_CANTRUN; // can't move: motor isn't stopping + switch(state[i]){ + case STP_ERR: + case STP_STALL: + case STP_RELAX: + break; + default: // moving state + return ERR_CANTRUN; + } if(newpos > (int32_t)the_conf.maxsteps[i] || newpos < -(int32_t)the_conf.maxsteps[i] || newpos == stppos[i]) return ERR_BADVAL; // too big position or zero - Nstalled = 0; + Nstalled[i] = (state[i] == STP_STALL) ? -(NSTALLEDMAX*5) : 0; // give some more chances to go out of stall state + stopflag[i] = 0; targstppos[i] = newpos; prevencpos[i] = encoder_position(i); prevstppos[i] = stppos[i]; @@ -193,7 +205,26 @@ errcodes motor_relmove(uint8_t i, int32_t relsteps){ return motor_absmove(i, stppos[i] + relsteps); } -void stopmotor(uint8_t i){ +errcodes motor_relslow(uint8_t i, int32_t relsteps){ + errcodes e = motor_absmove(i, stppos[i] + relsteps); + if(ERR_OK == e){ + state[i] = STP_MVSLOW; + } + return e; +} + +// emergency stop and clear errors +void emstopmotor(uint8_t i){ + switch(state[i]){ + case STP_ERR: // clear error state + case STP_STALL: + state[i] = STP_RELAX; + // fallthrough + case STP_RELAX: // do nothing in stopping state + return; + default: + break; + } stopflag[i] = 1; } @@ -205,7 +236,7 @@ stp_state getmotstate(uint8_t i){ void addmicrostep(uint8_t i){ static volatile uint16_t microsteps[MOTORSNO] = {0}; // current microsteps position if(ESW_state(i)){ // ESW active - switch(the_conf.ESW_reaction[i]){ + switch(ESW_reaction[i]){ case ESW_ANYSTOP: // stop motor in any direction stopflag[i] = 1; break; @@ -235,7 +266,11 @@ void addmicrostep(uint8_t i){ mottimers[i]->CR1 &= ~TIM_CR1_CEN; // stop timer if(the_conf.motflags[i].donthold) MOTOR_DIS(i); // turn off power - state[i] = STP_RELAX; + if(stallflags[i] == STALL_STOP){ + stallflags[i] = STALL_NO; + state[i] = STP_STALL; + }else + state[i] = STP_RELAX; SEND("MOTOR"); bufputchar('0'+i); SEND(" stop @"); printi(stppos[i]); newline(); } } @@ -264,26 +299,29 @@ static t_stalled chkSTALL(uint8_t i){ difsign = -difsign; } if(Dstp < 10){ // didn't move even @ 10 steps + stallflags[i] = STALL_NO; return STALL_NO; } if(Denc < 0){ Denc = -Denc; difsign = -difsign; } - if(difsign == -1){ // motor and encoder moves to different sides!!! + if(difsign == -1){ // motor and encĪder moves to different sides!!! Denc = -Denc; // init STALL state } prevencpos[i] = curencpos; + // TODO: check if it should be here getpos(i, &curstppos); // recalculate current position stppos[i] = curstppos; prevstppos[i] = curstppos; if(Denc < the_conf.encperstepmin[i]*Dstp || the_conf.encperstepmax[i]*Dstp < Denc){ // stall? SEND("MOTOR"); bufputchar('0'+i); SEND(" Denc="); printi(Denc); SEND(", Dstp="); printu(Dstp); SEND(", speed="); printu(curspeed[i]); - if(++Nstalled > NSTALLEDMAX){ + if(++Nstalled[i] > NSTALLEDMAX){ stopflag[i] = 1; - Nstalled = 0; + Nstalled[i] = 0; SEND(" --- STALL!"); NL(); + stallflags[i] = STALL_STOP; return STALL_STOP; }else{ uint16_t spd = curspeed[i] >> 1; // speed / 2 @@ -291,11 +329,11 @@ static t_stalled chkSTALL(uint8_t i){ // now recalculate acc/dec parameters calcacceleration(i); SEND(" --- pre-stall, newspeed="); printu(curspeed[i]); NL(); + stallflags[i] = STALL_ONCE; return STALL_ONCE; } } - prevstppos[i] = curstppos; - Nstalled = 0; + Nstalled[i] = 0; return STALL_NO; } @@ -311,20 +349,22 @@ static void chkstepper(int i){ int32_t newspeed; switch(state[i]){ case STP_RELAX: // check if need to keep current position - if(the_conf.motflags[i].haveencoder && the_conf.motflags[i].keeppos){ + if(the_conf.motflags[i].haveencoder){ getpos(i, &newspeed); int32_t diff = stppos[i] - newspeed; // correct `curpos` counter by encoder - if(diff){ + if(diff){ // correct current stppos by encoder SEND("MOTOR"); bufputchar('0'+i); SEND(" diff="); printi(diff); SEND(", change stppos from "); printi(stppos[i]); SEND(" to "); printi(newspeed); NL(); stppos[i] = newspeed; } - diff = targstppos[i] - newspeed; // check whether we need to change position - if(diff){ // try to correct position - SEND("MOTOR"); bufputchar('0'+i); - SEND(" curpos="); printi(newspeed); SEND(", need="); printi(targstppos[i]); NL(); - motor_absmove(i, targstppos[i]); + if(the_conf.motflags[i].keeppos){ // keep old position + diff = targstppos[i] - newspeed; // check whether we need to change position + if(diff){ // try to correct position + SEND("MOTOR"); bufputchar('0'+i); + SEND(" curpos="); printi(newspeed); SEND(", need="); printi(targstppos[i]); NL(); + motor_absmove(i, targstppos[i]); + } } } break; @@ -383,43 +423,76 @@ static void chkstepper(int i){ //SEND("spd="); printu(curspeed[i]); SEND(", pos="); printi(stppos[i]); newline(); } break; - default: // STP_MVSLOW, STALL, ERR -> do nothing - return; + case STP_MVSLOW: + chkSTALL(i); + break; + default: // STALL, ERR -> do nothing, check mvzerostate + break; } switch(mvzerostate[i]){ case M0FAST: - if(state[i] == STP_RELAX){ // stopped -> move to + - if(ERR_OK != motor_relmove(i, 50)){ + if(state[i] == STP_RELAX || state[i] == STP_STALL){ // stopped -> move to + + SEND("M0FAST: motor stopped\n"); + if(ERR_OK != motor_relslow(i, 1000)){ + SEND("Can't move\n"); state[i] = STP_ERR; mvzerostate[i] = M0RELAX; + ESW_reaction[i] = the_conf.ESW_reaction[i]; }else - mvzerostate[i] = M0PLUS; - } - break; - case M0PLUS: - if(state[i] == STP_RELAX){ // stopped -> move - if(ERR_OK != motor_relmove(i, -100)){ - state[i] = STP_ERR; - mvzerostate[i] = M0RELAX; - }else{ - state[i] = STP_MVSLOW; mvzerostate[i] = M0SLOW; - } } break; case M0SLOW: - if(state[i] == STP_RELAX){ - encpos[i] = 0; + if(0 == ESW_state(i)){ // moved out of limit switch - can stop + emstopmotor(i); + } + if(state[i] == STP_RELAX || state[i] == STP_STALL){ + SEND("M0SLOW: motor stopped @ 0\n"); NL(); + ESW_reaction[i] = the_conf.ESW_reaction[i]; + prevencpos[i] = encpos[i] = 0; stppos[i] = 0; - mottimers[i]->CNT = 0; // set encoder counter to zero + enctimers[i]->CNT = 0; // set encoder counter to zero mvzerostate[i] = M0RELAX; } break; - default: // RELAX: do nothing + default: // RELAX, STALL: do nothing break; } } +errcodes motor_goto0(uint8_t i){ + errcodes e = motor_absmove(i, -the_conf.maxsteps[i]); + if(ERR_OK != e) return e; + ESW_reaction[i] = ESW_STOPMINUS; + mvzerostate[i] = M0FAST; + return e; +} + +// smooth motor stopping +void stopmotor(uint8_t i){ + switch(state[i]){ + case STP_MVSLOW: // immeditially stop on slowest speed + stopflag[i] = 1; + return; + break; + case STP_MOVE: // stop only in moving states + case STP_ACCEL: + break; + default: // do nothing in other states + return; + } + int32_t newstoppos = stppos[i]; // calculate steps need for stop (we can be @acceleration phase!) + int32_t add = (curspeed[i] * curspeed[i]) / the_conf.accel[i] / 2; + if(motdir[i] > 0){ + newstoppos += add; + if(newstoppos < (int32_t)the_conf.maxsteps[i]) targstppos[i] = newstoppos; + }else{ + newstoppos -= add; + if(newstoppos > -((int32_t)the_conf.maxsteps[i])) targstppos[i] = newstoppos; + } + TODECEL(); +} + void process_steppers(){ static uint32_t Tlast = 0; if(Tms - Tlast < MOTCHKINTERVAL) return; // hit every 10ms @@ -428,3 +501,7 @@ void process_steppers(){ chkstepper(i); } } + +uint8_t geteswreact(uint8_t i){ + return ESW_reaction[i]; +} diff --git a/F0-nolib/3steppersLB/steppers.h b/F0-nolib/3steppersLB/steppers.h index a710191..d9aa116 100644 --- a/F0-nolib/3steppersLB/steppers.h +++ b/F0-nolib/3steppersLB/steppers.h @@ -38,11 +38,12 @@ typedef enum{ } stp_state; // end-switches reaction -typedef enum{ +enum{ ESW_IGNORE, // don't stop @ end-switch ESW_ANYSTOP, // stop @ esw in any moving direction - ESW_STOPMINUS // stop only in negative moving -} esw_react; + ESW_STOPMINUS, // stop only in negative moving + ESW_AMOUNT // number of records +}; // find zero stages: fast -> 0, slow -> +, slow -> 0 @@ -57,7 +58,12 @@ 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(); diff --git a/F0-nolib/3steppersLB/strfunct.c b/F0-nolib/3steppersLB/strfunct.c index afc3f95..aa22dc4 100644 --- a/F0-nolib/3steppersLB/strfunct.c +++ b/F0-nolib/3steppersLB/strfunct.c @@ -396,7 +396,7 @@ void getcounter(_U_ char *txt){ void wdcheck(_U_ char *txt){ while(1){nop();} } - +/* void stp_check(char *txt){ uint8_t N = *txt - '0'; if(N < 3){ @@ -411,51 +411,135 @@ void stp_check(char *txt){ mottimers[N]->CR1 &= ~TIM_CR1_CEN; } } -} +}*/ + typedef void(*specfpointer)(char *arg); -typedef struct{ - const char *command; - specfpointer function; - const char *help; -} speccommands; +enum{ + SCMD_IGNORE, + SCMD_DELIGNLIST, + SCMD_DFU, + SCMD_FILTER, + SCMD_CANSPEED, + SCMD_CANID, + SCMD_LISTFILTERS, + SCMD_IGNBUF, + SCMD_PAUSE, + SCMD_RESUME, + SCMD_SEND, + SCMD_DUMPCONF, + SCMD_GETCTR, + SCMD_WD, + //SCMD_ST, + SCMD_AMOUNT +}; -const speccommands scmdlist[] = { - {"ignore", addIGN, "add ID to ignore list (max 10 IDs)"}, - {"delignlist", delignlist, "delete ignore list"}, - {"dfu", bootldr, "activate DFU mode"}, - {"filter", add_filter, "add/modify filter, format: bank# FIFO# mode(M/I) num0 [num1 [num2 [num3]]]"}, - {"canspeed", CANini, "CAN bus speed"}, - {"canid", canid, "get/set CAN ID"}, - {"listfilters", list_filters, "list all active filters"}, - {"ignbuf", print_ign_buf, "print ignore buffer"}, - {"pause", inpause, "pause IN packets displaying"}, - {"resume", inresume, "resume IN packets displaying"}, - {"send", sendCANcommand, "send data over CAN: send ID byte0 .. byteN"}, - {"dumpconf", dump_userconf, "dump current configuration"}, - {"getctr", getcounter, "get TIM1/2/3 counters"}, - {"wd", wdcheck, "check watchdog"}, - {"st", stp_check, "check steppers"}, - {NULL, NULL, NULL} +typedef struct{ + int cmd_code; // CMD_... or <0 for usb-only commands + const char *command; // text command (up to 65536 commands) + const char *help; // help message for text protocol +} commands; + +// the main commands list, index is CAN command code +static const commands textcommands[] = { + // different commands + {0, "", "Different commands:"}, // DELIMETERS + {CMD_ADC, "adc", "get ADC values"}, + {CMD_BUTTONS, "button", "get buttons state"}, + {CMD_BUZZER, "buzzer", "change buzzer state (1/0)"}, + {CMD_ESWSTATE, "esw", "get end switches state"}, + {CMD_EXT, "ext", "external outputs"}, + {CMD_MCUT, "mcut", "get MCU T"}, + {CMD_MCUVDD, "mcuvdd", "get MCU Vdd"}, + {CMD_PING, "ping", "echo given command back"}, + {CMD_PWM, "pwm", "pwm value"}, + {CMD_RELAY, "relay", "change relay state (1/0)"}, + {CMD_RESET, "reset", "reset MCU"}, + {CMD_TIMEFROMSTART, "time", "get time from start"}, + // configuration + {0, "", "Confuguration:"}, + {CMD_ACCEL, "accel", "set/get accel/decel (steps/s^2)"}, + {CMD_ENCREV, "encrev", "set/get max encoder's pulses per revolution"}, + {CMD_ENCSTEPMAX, "encstepmax", "maximal encoder ticks per step"}, + {CMD_ENCSTEPMIN, "encstepmin", "minimal encoder ticks per step"}, + {CMD_ESWREACT, "eswreact", "end-switches reaction"}, + {CMD_MAXSPEED, "maxspeed", "set/get max speed (steps per sec)"}, + {CMD_MAXSTEPS, "maxsteps", "set/get max steps (from zero)"}, + {CMD_MICROSTEPS, "microsteps", "set/get microsteps settings"}, + {CMD_MINSPEED, "minspeed", "set/get min speed (steps per sec)"}, + {CMD_MOTFLAGS, "motflags", "set/get motorN flags"}, + {CMD_SAVECONF, "saveconf", "save current configuration"}, + {CMD_SPEEDLIMIT, "speedlimit", "get limiting speed for current microsteps"}, + // motors' commands + {0, "", "Motors' commands:"}, + {CMD_ABSPOS, "abspos", "set/get position (in steps)"}, + {CMD_EMERGSTOPALL, "emerg", "emergency stop all motors"}, + {CMD_EMERGSTOP, "emstop", "emergency stop motor (right now)"}, + {CMD_ENCPOS, "encpos", "set/get encoder's position"}, + {CMD_GOTOZERO, "gotoz", "find zero position & refresh counters"}, + {CMD_REINITMOTORS, "motreinit", "re-init motors after configuration changed"}, + {CMD_RELPOS, "relpos", "set relative steps, get remaining"}, + {CMD_RELSLOW, "relslow", "set relative steps @ lowest speed"}, + {CMD_MOTORSTATE, "state", "get motor state"}, + {CMD_STOP, "stop", "smooth motor stopping"}, + // USB-only commands + {0, "", "USB-only commands:"}, + {-SCMD_CANID, "canid", "get/set CAN ID"}, + {-SCMD_CANSPEED, "canspeed", "CAN bus speed"}, + {-SCMD_DELIGNLIST, "delignlist", "delete ignore list"}, + {-SCMD_DFU, "dfu", "activate DFU mode"}, + {-SCMD_DUMPCONF, "dumpconf", "dump current configuration"}, + {-SCMD_FILTER, "filter", "add/modify filter, format: bank# FIFO# mode(M/I) num0 [num1 [num2 [num3]]]"}, + {-SCMD_GETCTR, "getctr", "get TIM1/2/3 counters"}, + {-SCMD_IGNBUF, "ignbuf", "print ignore buffer"}, + {-SCMD_IGNORE, "ignore", "add ID to ignore list (max 10 IDs)"}, + {-SCMD_LISTFILTERS, "listfilters", "list all active filters"}, + {-SCMD_PAUSE, "pause", "pause IN packets displaying"}, + {-SCMD_RESUME, "resume", "resume IN packets displaying"}, + {-SCMD_SEND, "send", "send data over CAN: send ID byte0 .. byteN"}, + //{-SCMD_ST, "st", "check steppers"}, + {-SCMD_WD, "wd", "check watchdog"}, + {0, NULL, NULL} +}; + + +static specfpointer speccmdlist[SCMD_AMOUNT] = { + [SCMD_IGNORE] = addIGN, + [SCMD_DELIGNLIST] = delignlist, + [SCMD_DFU] = bootldr, + [SCMD_FILTER] = add_filter, + [SCMD_CANSPEED] = CANini, + [SCMD_CANID] = canid, + [SCMD_LISTFILTERS] = list_filters, + [SCMD_IGNBUF] = print_ign_buf, + [SCMD_PAUSE] = inpause, + [SCMD_RESUME] = inresume, + [SCMD_SEND] = sendCANcommand, + [SCMD_DUMPCONF] = dump_userconf, + [SCMD_GETCTR] = getcounter, + [SCMD_WD] = wdcheck, + //[SCMD_ST] = stp_check, }; static void showHelp(){ SEND("https://github.com/eddyem/stm32samples/tree/master/F0-nolib/3steppersLB build#" BUILD_NUMBER " @ " BUILD_DATE "\n"); SEND("Common commands format is cmd[ N[ = val]]\n\twhere N is command argument (0..127), val is its value\n"); - SEND("Common commands:\n"); - for(int i = 0; i < CMD_AMOUNT; ++i){ - bufputchar('\t'); SEND(cmdlist[i].command); SEND(" - "); - SEND(cmdlist[i].help); newline(); - } - SEND("USB-only commands:\n"); - const speccommands *cmd = scmdlist; + //SEND("Commands list:\n"); + const commands *cmd = textcommands; while(cmd->command){ - bufputchar('\t'); SEND(cmd->command); SEND(" - "); + if(*cmd->command){ + bufputchar('\t'); + SEND(cmd->command); /*SEND(" ("); + if(cmd->cmd_code < 0) bufputchar('u'); + else bufputchar('c'); + SEND(") - ");*/ + SEND(" - "); + } SEND(cmd->help); newline(); ++cmd; } - NL(); + sendbuf(); } /** @@ -474,7 +558,6 @@ static void showHelp(){ void cmd_parser(char *txt){ char cmd[32], *pcmd = cmd; int i = 0; - // first try to find command in `cmdlist` char *eptr = omit_spaces(txt); if(!*eptr) return; while(*eptr && i < 30){ @@ -483,59 +566,57 @@ void cmd_parser(char *txt){ ++i; } *pcmd = 0; + if(cmd[0] == 0){ // empty command + showHelp(); + return; + } if(eptr && *eptr){ eptr = omit_spaces(eptr); } // find command - int idx = 0; - do{ - if(0 == cmpstr(cmdlist[idx].command, cmd)) break; - }while(++idx < CMD_AMOUNT); - if(idx < CMD_AMOUNT){ + const commands *c = textcommands; + while(c->command){ + if(0 == cmpstr(c->command, cmd)){ #ifdef EBUG SEND("Find known command: "); SEND(cmd); if(eptr && *eptr) SEND(", args: "); SEND(eptr); NL(); #endif - uint8_t par = CANMESG_NOPAR; - int32_t val = 0; - if(eptr && *eptr){ - char *nxt = getnum(eptr, &val); - if(nxt && nxt != eptr){ // command has parameter? - if(val < 0 || val >= CANMESG_NOPAR){ - SEND("Command parameter should be 0..126!"); NL(); - return; + if(c->cmd_code < 0){ // USB-only command + speccmdlist[-(c->cmd_code)](eptr); + }else{ // common command + uint8_t par = CANMESG_NOPAR; + int32_t val = 0; + if(eptr && *eptr){ + char *nxt = getnum(eptr, &val); + if(nxt && nxt != eptr){ // command has parameter? + if(val < 0 || val >= CANMESG_NOPAR){ + SEND("Command parameter should be 0..126!"); NL(); + return; + } + par = (uint8_t)val; + }else nxt = eptr; + eptr = getchr(nxt, '='); + if(eptr){ // command has value? + eptr = omit_spaces(eptr + 1); + nxt = getnum(eptr, &val); + if(nxt != eptr){ + par |= 0x80; // setter + } + } } - par = (uint8_t)val; - }else nxt = eptr; - eptr = getchr(nxt, '='); - if(eptr){ // command has value? - eptr = omit_spaces(eptr + 1); - nxt = getnum(eptr, &val); - if(nxt != eptr){ - par |= 0x80; // setter + // here we got command & ppar/pval -> call CMD + errcodes retcode = cmdlist[c->cmd_code](par, &val); + SEND(cmd); + par &= 0x7f; + if(par != CANMESG_NOPAR) printu(par); + bufputchar('='); printi(val); + SEND(" ("); printuhex((uint32_t)val); bufputchar(')'); + if(ERR_OK != retcode){ + SEND("\nERRCODE="); + printu(retcode); } } - } - // here we got command & ppar/pval -> call CMD - errcodes retcode = cmdlist[idx].function(par, &val); - SEND(cmd); - par &= 0x7f; - if(par != CANMESG_NOPAR) printu(par); - bufputchar('='); printi(val); - SEND(" ("); printuhex((uint32_t)val); bufputchar(')'); - if(ERR_OK != retcode){ - SEND("\nERRCODE="); - printu(retcode); - } - NL(); - return; - } - /*-> find USB-only commands here and show help if not found <-*/ - const speccommands *c = scmdlist; - while(c->command){ - if(0 == cmpstr(c->command, cmd)){ - c->function(eptr); NL(); return; } diff --git a/F0-nolib/3steppersLB/version.inc b/F0-nolib/3steppersLB/version.inc index 66444c1..3a5ed44 100644 --- a/F0-nolib/3steppersLB/version.inc +++ b/F0-nolib/3steppersLB/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "114" -#define BUILD_DATE "2021-11-17" +#define BUILD_NUMBER "129" +#define BUILD_DATE "2021-12-01" diff --git a/F0-nolib/CANbus_stepper/src/canstepper.bin b/F0-nolib/CANbus_stepper/src/canstepper.bin old mode 100755 new mode 100644 diff --git a/F0-nolib/Chiller/chiller.bin b/F0-nolib/Chiller/chiller.bin old mode 100755 new mode 100644 diff --git a/F0-nolib/F0_testbrd/pl2303.bin b/F0-nolib/F0_testbrd/pl2303.bin old mode 100755 new mode 100644 diff --git a/F0-nolib/QuadEncoder/encoder.bin b/F0-nolib/QuadEncoder/encoder.bin old mode 100755 new mode 100644 diff --git a/F0-nolib/Servo/servo.bin b/F0-nolib/Servo/servo.bin old mode 100755 new mode 100644 diff --git a/F0-nolib/Socket_fans/sockfans.bin b/F0-nolib/Socket_fans/sockfans.bin old mode 100755 new mode 100644 diff --git a/F0-nolib/TM1637/tm1637.bin b/F0-nolib/TM1637/tm1637.bin old mode 100755 new mode 100644 diff --git a/F0-nolib/USBHID/usbhid.bin b/F0-nolib/USBHID/usbhid.bin old mode 100755 new mode 100644 diff --git a/F0-nolib/USB_pl2303_snippet/usb.bin b/F0-nolib/USB_pl2303_snippet/usb.bin old mode 100755 new mode 100644 diff --git a/F0-nolib/blink/blink.bin b/F0-nolib/blink/blink.bin old mode 100644 new mode 100755 diff --git a/F0-nolib/canbus/src/canbus.bin b/F0-nolib/canbus/src/canbus.bin old mode 100755 new mode 100644 diff --git a/F0-nolib/htu21d_nucleo/usart.bin b/F0-nolib/htu21d_nucleo/usart.bin old mode 100755 new mode 100644 diff --git a/F0-nolib/inc/F0 b/F0-nolib/inc/F0 index ba957c0..0be4819 120000 --- a/F0-nolib/inc/F0 +++ b/F0-nolib/inc/F0 @@ -1 +1 @@ -/home/eddy/Yandex.Disk/Projects/stm32samples/F0-nolib/inc/Fx \ No newline at end of file +Fx \ No newline at end of file diff --git a/F0-nolib/morze/morze.bin b/F0-nolib/morze/morze.bin old mode 100755 new mode 100644 diff --git a/F0-nolib/pl2303/pl2303.bin b/F0-nolib/pl2303/pl2303.bin old mode 100755 new mode 100644 diff --git a/F0-nolib/tsys01_nucleo/tsys01.bin b/F0-nolib/tsys01_nucleo/tsys01.bin old mode 100755 new mode 100644 diff --git a/F0-nolib/uart_blink/uartblink.bin b/F0-nolib/uart_blink/uartblink.bin old mode 100755 new mode 100644 diff --git a/F0-nolib/uart_blink_dma/uartblink.bin b/F0-nolib/uart_blink_dma/uartblink.bin old mode 100755 new mode 100644 diff --git a/F0-nolib/uart_nucleo/usart.bin b/F0-nolib/uart_nucleo/usart.bin old mode 100755 new mode 100644 diff --git a/F0-nolib/usbcan/usbcan.bin b/F0-nolib/usbcan/usbcan.bin old mode 100644 new mode 100755 diff --git a/F0-nolib/usbcan_relay/usbcan.bin b/F0-nolib/usbcan_relay/usbcan.bin old mode 100644 new mode 100755 diff --git a/F0/blink/blink.bin b/F0/blink/blink.bin old mode 100755 new mode 100644 diff --git a/F0/uart/uart.bin b/F0/uart/uart.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/BMP180/BMP180.bin b/F1-nolib/BMP180/BMP180.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/BMP280/BMP280.bin b/F1-nolib/BMP280/BMP280.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/CDC_ACM/cdcacm.bin b/F1-nolib/CDC_ACM/cdcacm.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/DHT22_DHT11/DHT22.bin b/F1-nolib/DHT22_DHT11/DHT22.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/DS18/DS18.bin b/F1-nolib/DS18/DS18.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/F1_testbrd/pl2303.bin b/F1-nolib/F1_testbrd/pl2303.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/I2Cscan/I2Cscan.bin b/F1-nolib/I2Cscan/I2Cscan.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/LED_Screen/LEDscreen.bin b/F1-nolib/LED_Screen/LEDscreen.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/LED_Screen/genlist b/F1-nolib/LED_Screen/genlist old mode 100755 new mode 100644 diff --git a/F1-nolib/LED_Screen/scrtest/scrtest b/F1-nolib/LED_Screen/scrtest/scrtest old mode 100755 new mode 100644 diff --git a/F1-nolib/MAX7219_screen/MAX7219.bin b/F1-nolib/MAX7219_screen/MAX7219.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/PL2303/pl2303.bin b/F1-nolib/PL2303/pl2303.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/RGB_LED_Screen/RGBLEDscreen.bin b/F1-nolib/RGB_LED_Screen/RGBLEDscreen.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/RGB_LED_Screen/getrand b/F1-nolib/RGB_LED_Screen/getrand old mode 100755 new mode 100644 diff --git a/F1-nolib/RGB_LED_Screen/proto.c b/F1-nolib/RGB_LED_Screen/proto.c deleted file mode 100644 index 63ffb0f..0000000 --- a/F1-nolib/RGB_LED_Screen/proto.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * This file is part of the RGBLEDscreen project. - * Copyright 2020 Edward V. Emelianov . - * - * 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 . - */ - -#include "adcrandom.h" -#include "balls.h" -#include "fonts.h" -#include "proto.h" -#include "screen.h" -#include "usb.h" - -extern uint8_t countms, rainbow, balls; -extern uint32_t Tms; - -char *omit_spaces(const char *buf){ - while(*buf){ - if(*buf > ' ') break; - ++buf; - } - return (char*)buf; -} - -// In case of overflow return `buf` and N==0xffffffff -// read decimal number & return pointer to next non-number symbol -static 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 (char*)buf; -} -// read hexadecimal number (without 0x prefix!) -static char *gethex(const char *buf, uint32_t *N){ - char *start = (char*)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 (char*)buf; -} -// read octal number (without 0 prefix!) -static char *getoct(const char *buf, uint32_t *N){ - 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 (char*)buf; -} -// read binary number (without b prefix!) -static char *getbin(const char *buf, uint32_t *N){ - 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 (char*)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) - */ -char *getnum(const char *txt, uint32_t *N){ - char *nxt = NULL; - 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; -} - -const char* helpmsg = - "'0/1' - screen off/on\n" - "'2,3' - select font\n" - "'A' - get ADC values\n" - "'B' - start/stop rainBow\n" - "'b' - start/stop Balls\n" - "'C' - clear screen with given color\n" - "'F' - set foreground color\n" - "'G' - get 100 random numbers\n" - "'f' - get FPS\n" - "'R' - software reset\n" - "'W' - test watchdog\n" - "'Zz' -start/stop counting ms\n" - "Any text - put text @ screen\n" -; - -const char *parse_cmd(const char *buf){ - uint32_t N; - if(buf[1] == '\n'){ // one symbol commands - switch(*buf){ - case '0': - ScreenOFF(); - return "OFF\n"; - break; - case '1': - ScreenON(); - return "ON\n"; - break; - case '2': - if(choose_font(FONT14)) return "Font14\n"; - return "err\n"; - break; - case '3': - if(choose_font(FONT16)) return "Font16\n"; - return "err\n"; - break; - case 'A': - USB_send("Tsens="); USB_send(u2str(getADCval(0))); - USB_send("\nVref="); USB_send(u2str(getADCval(1))); - USB_send("\nRand="); USB_send(u2str(getRand())); - USB_send("\n"); - return NULL; - break; - case 'B': - if(rainbow){ - rainbow = 0; - return "Stop rainbow\n"; - }else{ - rainbow = 1; - return "Start rainbow\n"; - } - break; - case 'b': - if(balls){ - balls = 0; - return "Stop balls\n"; - }else{ - balls_init(); - balls = 1; - return "Start balls\n"; - } - case 'f': - if(SCREEN_RELAX == getScreenState()) return "Screen is inactive\n"; - USB_send("FPS="); - USB_send(u2str(getFPS())); - USB_send("\n"); - return NULL; - break; - case 'G': - /*USB_send(u2str(Tms)); USB_send("\n"); - for(int i=0; i < 1000; ++i) getRand(); - USB_send(u2str(Tms)); USB_send("\n");*/ - for(int i = 0; i < 100; ++i){ - USB_send(u2str(getRand())); - USB_send("\n"); - } - return NULL; - break; - case 'R': - USB_send("Soft reset\n"); - NVIC_SystemReset(); - break; - case 'W': - USB_send("Wait for reboot\n"); - while(1){nop();}; - break; - case 'Z': - countms = 1; - return "Start\n"; - break; - case 'z': - countms = 0; - return "Stop\n"; - break; - default: - return helpmsg; - } - return NULL; - }else{ - switch(*buf){ - case 'C': - if(getnum(buf+1, &N)){ - ScreenOFF(); - setBGcolor(N); - ClearScreen(); - ScreenON(); - return "Background color\n"; - } - return "Wrong color\n"; - break; - case 'F': - if(getnum(buf+1, &N)){ - setFGcolor(N); - return "Foreground color\n"; - } - return "Wrong color\n"; - break; - default: - ScreenOFF(); - ClearScreen(); - PutStringAt(1, curfont->height + 3, buf); - ScreenON(); - } - return buf; - } - return NULL; -} - -// return string with number `val` -char *u2str(uint32_t val){ - static char strbuf[11]; - char *bufptr = &strbuf[10]; - *bufptr = 0; - if(!val){ - *(--bufptr) = '0'; - }else{ - while(val){ - *(--bufptr) = val % 10 + '0'; - val /= 10; - } - } - return bufptr; -} diff --git a/F1-nolib/RGB_LED_Screen/proto.c b/F1-nolib/RGB_LED_Screen/proto.c new file mode 120000 index 0000000..ef1f2e9 --- /dev/null +++ b/F1-nolib/RGB_LED_Screen/proto.c @@ -0,0 +1 @@ +/home/eddy/Yandex.Disk/Projects/mytakepic/.hg/wcache/checklink-target \ No newline at end of file diff --git a/F1-nolib/SI7005_HTU21D/si7005.bin b/F1-nolib/SI7005_HTU21D/si7005.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/SPI/SPI.bin b/F1-nolib/SPI/SPI.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/SevenCDCs/cdcacmcore.bin b/F1-nolib/SevenCDCs/cdcacmcore.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/Tetris/TETRIS.bin b/F1-nolib/Tetris/TETRIS.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/Tetris/getrand b/F1-nolib/Tetris/getrand old mode 100755 new mode 100644 diff --git a/F1-nolib/Tetris/main.c b/F1-nolib/Tetris/main.c deleted file mode 100644 index 0513d46..0000000 --- a/F1-nolib/Tetris/main.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * This file is part of the TETRIS project. - * Copyright 2021 Edward V. Emelianov . - * - * 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 . - */ - -#include "adcrandom.h" -#include "arkanoid.h" -#include "balls.h" -#include "buttons.h" -#include "fonts.h" -#include "hardware.h" -#include "menu.h" -#include "proto.h" -#include "screen.h" -#include "snake.h" -#include "tetris.h" -#include "usb.h" -#include "usb_lib.h" - -// timeout for autosleep (30s) -#define AUTOSLEEP_TMOUT (30000) - -volatile uint32_t Tms = 0; -uint8_t balls = 0; - -enum{ - STATE_MENU, - STATE_SNAKE, - STATE_TETRIS, - STATE_ARKANOID, - STATE_SLEEP, - STATE_GAMEOVER -} curstate = STATE_SLEEP; - -/* Called when systick fires */ -void sys_tick_handler(void){ - ++Tms; -} - -#define USBBUFSZ (127) -// usb getline -static char *get_USB(){ - static char tmpbuf[USBBUFSZ+1], *curptr = tmpbuf; - static int rest = USBBUFSZ; - int x = USB_receive(curptr); - curptr[x] = 0; - if(!x) return NULL; - if(curptr[x-1] == '\n'){ - curptr = tmpbuf; - rest = USBBUFSZ; - return tmpbuf; - } - curptr += x; rest -= x; - if(rest <= 0){ // buffer overflow - curptr = tmpbuf; - rest = USBBUFSZ; - USB_send("USB buffer overflow\n"); - } - return NULL; -} - -static void process_menu(){ - switch(menu_activated()){ - case MENU_SLEEP: - USB_send("Select 'Sleep'\n"); - ScreenOFF(); - curstate = STATE_SLEEP; - break; - case MENU_BALLS: - USB_send("Select 'Balls'\n"); - if(balls){ - balls = 0; - }else{ - curstate = STATE_SLEEP; - balls_init(); - balls = 1; - } - break; - case MENU_SNAKE: - USB_send("Select 'Snake'\n"); - snake_init(); - curstate = STATE_SNAKE; - break; - case MENU_TETRIS: - USB_send("Select 'Tetris'\n"); - tetris_init(); - curstate = STATE_TETRIS; - break; - case MENU_ARKANOID: - USB_send("Select 'Arkanoid'\n"); - arkanoid_init(); - curstate = STATE_ARKANOID; - default: - break; - } -} - -static void gotomenu(){ - curstate = STATE_MENU; - clear_events(); - show_menu(); -} - -int main(void){ - uint32_t lastT = 0; - sysreset(); - StartHSE(); - SysTick_Config(72000); - RCC->CSR |= RCC_CSR_RMVF; // remove reset flags - - hw_setup(); - USBPU_OFF(); - adc_setup(); - USB_setup(); - //iwdg_setup(); - USBPU_ON(); - - keyevent evt; - while(1){ - if(Tms - lastT > 499){ - LED_blink(LED0); - lastT = Tms; - } - IWDG->KR = IWDG_REFRESH; - if(balls) process_balls(); - process_keys(); - switch(curstate){ - case STATE_SLEEP: - if(keystate(KEY_M, &evt) && evt == EVT_RELEASE){ - USB_send("Activate menu\n"); - gotomenu(); - } - break; - case STATE_MENU: - process_menu(); - if(Tms - lastUnsleep > AUTOSLEEP_TMOUT){ - USB_send("Autosleep\n"); - ScreenOFF(); - curstate = STATE_SLEEP; - } - break; - case STATE_SNAKE: - if(!snake_proces()){ - show_gameover(); - curstate = STATE_GAMEOVER; - } - break; - case STATE_TETRIS: - if(!tetris_process()){ - show_gameover(); - curstate = STATE_GAMEOVER; - } - break; - case STATE_ARKANOID: - if(!arkanoid_process()){ - show_gameover(); - curstate = STATE_GAMEOVER; - } - break; - case STATE_GAMEOVER: // show gameover screen - if(keystate(KEY_M, &evt) && evt == EVT_RELEASE){ - gotomenu(); - }else if(Tms - lastUnsleep > AUTOSLEEP_TMOUT){ - USB_send("Autosleep\n"); - ScreenOFF(); - curstate = STATE_SLEEP; - } - break; - } - - usb_proc(); - char *txt; const char *ans; - if((txt = get_USB())){ - ans = parse_cmd(txt); - if(ans) USB_send(ans); - } - } - return 0; -} - diff --git a/F1-nolib/Tetris/main.c b/F1-nolib/Tetris/main.c new file mode 120000 index 0000000..ef1f2e9 --- /dev/null +++ b/F1-nolib/Tetris/main.c @@ -0,0 +1 @@ +/home/eddy/Yandex.Disk/Projects/mytakepic/.hg/wcache/checklink-target \ No newline at end of file diff --git a/F1-nolib/USB_HID/usbhid103.bin b/F1-nolib/USB_HID/usbhid103.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/chronometer/chrono.bin b/F1-nolib/chronometer/chrono.bin old mode 100644 new mode 100755 diff --git a/F1-nolib/chronometer_v2/chrono.bin b/F1-nolib/chronometer_v2/chrono.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/chronometer_v3/chrono.bin b/F1-nolib/chronometer_v3/chrono.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/led_blink/blink.bin b/F1-nolib/led_blink/blink.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/pl2303_snippet/pl2303.bin b/F1-nolib/pl2303_snippet/pl2303.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/pl2303_snippet_naked/pl2303.bin b/F1-nolib/pl2303_snippet_naked/pl2303.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/pwmdmatest/pwmtest.bin b/F1-nolib/pwmdmatest/pwmtest.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/pwmtest/pwmtest.bin b/F1-nolib/pwmtest/pwmtest.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/uart/uart.bin b/F1-nolib/uart/uart.bin old mode 100755 new mode 100644 diff --git a/F1-nolib/ws2815/ws2815.bin b/F1-nolib/ws2815/ws2815.bin old mode 100755 new mode 100644 diff --git a/F1/1_wire/onewire.bin b/F1/1_wire/onewire.bin old mode 100755 new mode 100644 diff --git a/F1/2.8TFT/dma_gpio.bin b/F1/2.8TFT/dma_gpio.bin old mode 100755 new mode 100644 diff --git a/F1/DMA_GPIO/dma_gpio.bin b/F1/DMA_GPIO/dma_gpio.bin old mode 100755 new mode 100644 diff --git a/F1/GPIO_TIM/tim_gpio.bin b/F1/GPIO_TIM/tim_gpio.bin old mode 100755 new mode 100644 diff --git a/F1/GPS+ultrasonic/timelapse.bin b/F1/GPS+ultrasonic/timelapse.bin old mode 100755 new mode 100644 diff --git a/F1/GPS/GPS.bin b/F1/GPS/GPS.bin old mode 100755 new mode 100644 diff --git a/F1/Jeep_generator/jeep_generator.bin b/F1/Jeep_generator/jeep_generator.bin old mode 100755 new mode 100644 diff --git a/F1/Timelapse_keyboard/timelapse.bin b/F1/Timelapse_keyboard/timelapse.bin old mode 100755 new mode 100644 diff --git a/F1/Timelapse_keyboard_only_lasers/timelapse.bin b/F1/Timelapse_keyboard_only_lasers/timelapse.bin old mode 100755 new mode 100644 diff --git a/F1/USBCDC_template/usb_cdc_simple.bin b/F1/USBCDC_template/usb_cdc_simple.bin old mode 100755 new mode 100644 diff --git a/F1/canon_lens/canon_lens.bin b/F1/canon_lens/canon_lens.bin old mode 100755 new mode 100644 diff --git a/F1/distance_meters/ultrasonic.bin b/F1/distance_meters/ultrasonic.bin old mode 100755 new mode 100644 diff --git a/F1/hid_mouse_keyboard/usbhid.bin b/F1/hid_mouse_keyboard/usbhid.bin old mode 100755 new mode 100644 diff --git a/F1/keyboard_snippet/keyboard.bin b/F1/keyboard_snippet/keyboard.bin old mode 100755 new mode 100644 diff --git a/F1/matrix_keyboard/matrkeyb.bin b/F1/matrix_keyboard/matrkeyb.bin old mode 100755 new mode 100644 diff --git a/F1/nokia5110/nokia5110.bin b/F1/nokia5110/nokia5110.bin old mode 100755 new mode 100644 diff --git a/F1/simple_cdc/usb_cdc_simple.bin b/F1/simple_cdc/usb_cdc_simple.bin old mode 100755 new mode 100644 diff --git a/F1/stepper_motion/usb_cdc_simple.bin b/F1/stepper_motion/usb_cdc_simple.bin old mode 100755 new mode 100644 diff --git a/F1/ultrasonic/ultrasonic.bin b/F1/ultrasonic/ultrasonic.bin old mode 100755 new mode 100644 diff --git a/F303-nolib/blink/blink.bin b/F303-nolib/blink/blink.bin old mode 100755 new mode 100644 diff --git a/F303-nolib/usart1/usart1.bin b/F303-nolib/usart1/usart1.bin old mode 100755 new mode 100644 diff --git a/F303-nolib/usarts/usart.bin b/F303-nolib/usarts/usart.bin old mode 100755 new mode 100644