From 6cb98bb7ed23e98139bb847f91a73c39205e916b Mon Sep 17 00:00:00 2001 From: Edward Emelianov Date: Mon, 3 Jun 2024 20:25:53 +0300 Subject: [PATCH] Always working, but some of schematics was wrong --- F1:F103/FX3U/Makefile | 4 +- F1:F103/FX3U/Readme.md | 0 F1:F103/FX3U/adc.c | 5 +- F1:F103/FX3U/adc.h | 7 +- F1:F103/FX3U/can.c | 6 +- F1:F103/FX3U/canproto.c | 85 ++++++++++--------- F1:F103/FX3U/canproto.h | 38 ++++----- F1:F103/FX3U/flash.c | 4 +- F1:F103/FX3U/flash.h | 5 +- F1:F103/FX3U/fx3u.bin | Bin 14032 -> 15168 bytes F1:F103/FX3U/fx3u.creator.user | 2 +- F1:F103/FX3U/hardware.c | 148 +++++++++++++++++++++++++++++++++ F1:F103/FX3U/hardware.h | 18 ++++ F1:F103/FX3U/main.c | 1 + F1:F103/FX3U/proto.c | 25 ++++-- F1:F103/FX3U/strfunc.h | 1 + F1:F103/FX3U/version.inc | 4 +- F1:F103/inc/ld/stm32f103xC.ld | 2 +- F1:F103/inc/ld/stm32f103xD.ld | 2 +- F1:F103/inc/ld/stm32f103xE.ld | 2 +- F1:F103/inc/ld/stm32f103xF.ld | 2 +- F1:F103/inc/ld/stm32f103xG.ld | 2 +- 22 files changed, 273 insertions(+), 90 deletions(-) create mode 100644 F1:F103/FX3U/Readme.md diff --git a/F1:F103/FX3U/Makefile b/F1:F103/FX3U/Makefile index 865c9a7..21d9860 100644 --- a/F1:F103/FX3U/Makefile +++ b/F1:F103/FX3U/Makefile @@ -1,8 +1,8 @@ BINARY := fx3u # MCU code -MCU ?= F103xC +MCU ?= F103xE # change this linking script depending on particular MCU model, -LDSCRIPT ?= stm32f103xC.ld +LDSCRIPT ?= stm32f103xE.ld DEFINES := -DSTM32F10X_HD INC_DIR := ../inc diff --git a/F1:F103/FX3U/Readme.md b/F1:F103/FX3U/Readme.md new file mode 100644 index 0000000..e69de29 diff --git a/F1:F103/FX3U/adc.c b/F1:F103/FX3U/adc.c index 466e7e0..fc3b3fb 100644 --- a/F1:F103/FX3U/adc.c +++ b/F1:F103/FX3U/adc.c @@ -36,8 +36,9 @@ void adc_setup(){ // sampling time - 239.5 cycles for channels 0, 16 and 17 ADC1->SMPR2 = ADC_SMPR2_SMP0; ADC1->SMPR1 = ADC_SMPR1_SMP16 | ADC_SMPR1_SMP17; - // sequence order: 0 -> 16 -> 17 - ADC1->SQR3 = (0 << 0) | (16<<5) | (17 << 10); + // sequence order: 1[0]->3[1]->14[2]->15[3]->10[4]->11[5] -> 16[tsen] -> 17[vdd] + ADC1->SQR3 = (1 << 0) | (3<<5) | (14 << 10) | (15 << 15) | (10 << 20) | (11 < 25); + ADC1->SQR2 = (16 << 0) | (17 << 5); ADC1->SQR1 = (ADC_CHANNELS - 1) << 20; // amount of conversions ADC1->CR1 = ADC_CR1_SCAN; // scan mode // DMA, continuous mode; enable vref & Tsens; enable SWSTART as trigger diff --git a/F1:F103/FX3U/adc.h b/F1:F103/FX3U/adc.h index cf7b82b..063bb90 100644 --- a/F1:F103/FX3U/adc.h +++ b/F1:F103/FX3U/adc.h @@ -22,7 +22,12 @@ // ADC channels in array enum{ - ADC_CH_VSEN = 0, // ADC_ch0 + ADC_CH_0 = 0, // ADC input channels + ADC_CH_1, + ADC_CH_2, + ADC_CH_3, + ADC_CH_4, + ADC_CH_5, ADC_CH_TSEN, // T sensor ADC_CH_VDD, // Vdd sensor ADC_CHANNELS diff --git a/F1:F103/FX3U/can.c b/F1:F103/FX3U/can.c index 1c1bb21..b851111 100644 --- a/F1:F103/FX3U/can.c +++ b/F1:F103/FX3U/can.c @@ -158,7 +158,7 @@ void CAN_setup(uint32_t speed){ CAN1->FA1R = CAN_FA1R_FACT0; /* (8) */ CAN1->FM1R = CAN_FM1R_FBM0; // filter 0 for FIFO0 - CAN1->sFilterRegister[0].FR1 = the_conf.CANID << 5; // (10) CANID and 0 + CAN1->sFilterRegister[0].FR1 = the_conf.CANIDin << 5; // (10) CANIDin and 0 if(flags.can_monitor){ /* (11) */ CAN1->FA1R |= CAN_FA1R_FACT1; // activate filter1 CAN1->sFilterRegister[1].FR1 = 0; // all packets @@ -299,7 +299,7 @@ CAN_status CAN_send(CAN_message *message){ * incoming data may have variable length */ TRUE_INLINE void parseCANcommand(CAN_message *msg){ - msg->ID = the_conf.CANID; // set own ID for broadcast messages + msg->ID = the_conf.CANIDout; // set output ID for all output messages // check PING if(msg->length != 0) run_can_cmd(msg); uint32_t Tstart = Tms; @@ -354,7 +354,7 @@ static void can_process_fifo(uint8_t fifo_num){ } } // run command for my or broadcast ID - if(msg.ID == the_conf.CANID || msg.ID == 0) parseCANcommand(&msg); + if(msg.ID == the_conf.CANIDin || msg.ID == 0) parseCANcommand(&msg); if(flags.can_monitor && CAN_messagebuf_push(&msg)) return; // error: buffer is full, try later *RFxR |= CAN_RF0R_RFOM0; // release fifo for access to next message } diff --git a/F1:F103/FX3U/canproto.c b/F1:F103/FX3U/canproto.c index 2df7fb0..cd43cad 100644 --- a/F1:F103/FX3U/canproto.c +++ b/F1:F103/FX3U/canproto.c @@ -57,36 +57,33 @@ static errcodes adcraw(CAN_message *msg){ *(uint32_t*)&msg->data[4] = getADCval(no); return ERR_OK; } -// get ADC voltage -static errcodes adcv(CAN_message *msg){ - FIXDL(msg); - uint8_t no = msg->data[2] & ~SETTER_FLAG; - if(no >= ADC_CH_TSEN) return ERR_BADPAR; - float v = getADCvoltage(no) /** the_conf.adcmul[no] * 100.f*/; - *(uint32_t*)&msg->data[4] = (uint32_t) v; - return ERR_OK; -} -// get/set CAN ID +// set common CAN ID / get CAN IN in static errcodes canid(CAN_message *msg){ if(ISSETTER(msg->data)){ - the_conf.CANID = *(uint32_t*)&msg->data[4]; + the_conf.CANIDin = the_conf.CANIDout = *(uint32_t*)&msg->data[4]; CAN_reinit(0); // setup with new ID }else FIXDL(msg); - *(uint32_t*)&msg->data[4] = the_conf.CANID; + *(uint32_t*)&msg->data[4] = the_conf.CANIDin; return ERR_OK; } -/* -// get/set ADC multiplier -static errcodes adcmul(CAN_message *msg){ - uint8_t no = msg->data[2] & ~SETTER_FLAG; - if(no >= ADC_TSENS) return ERR_BADPAR; +// get/set input CAN ID +static errcodes canidin(CAN_message *msg){ if(ISSETTER(msg->data)){ - the_conf.adcmul[no] = ((float)*(uint32_t*)&msg->data[4])/1000.f; + the_conf.CANIDin = *(uint32_t*)&msg->data[4]; + CAN_reinit(0); // setup with new ID }else FIXDL(msg); - *(uint32_t*)&msg->data[4] = (uint32_t)(1000.f * the_conf.adcmul[no]); + *(uint32_t*)&msg->data[4] = the_conf.CANIDin; return ERR_OK; } -*/ +// get/set output CAN ID +static errcodes canidout(CAN_message *msg){ + if(ISSETTER(msg->data)){ + the_conf.CANIDout = *(uint32_t*)&msg->data[4]; + }else FIXDL(msg); + *(uint32_t*)&msg->data[4] = the_conf.CANIDout; + return ERR_OK; +} + // save config static errcodes saveconf(CAN_message _U_ *msg){ if(0 == store_userconf()) return ERR_OK; @@ -97,33 +94,39 @@ static errcodes erasestor(CAN_message _U_ *msg){ if(0 == erase_storage(-1)) return ERR_OK; return ERR_CANTRUN; } -/* + // relay management static errcodes relay(CAN_message *msg){ + uint8_t no = OUTMAX+1; + if(msg->length > 2) no = msg->data[2] & ~SETTER_FLAG; if(ISSETTER(msg->data)){ - if(msg->data[4] == 1) RELAY_ON(); - else RELAY_OFF(); + if(set_relay(no, *(uint32_t*)&msg->data[4]) < 0) return ERR_BADPAR; }else FIXDL(msg); - *(uint32_t*)&msg->data[4] = RELAY_GET(); + int rval = get_relay(no); + if(rval < 0) return ERR_BADPAR; + *(uint32_t*)&msg->data[4] = (uint32_t)rval; return ERR_OK; } -// blocking ESW get status -static errcodes eswblk(CAN_message *msg){ - uint8_t no = msg->data[2] & ~SETTER_FLAG; - if(no > 1) return ERR_BADPAR; +// get current ESW status +static errcodes esw(CAN_message *msg){ + uint8_t no = INMAX+1; + if(msg->length > 2) no = msg->data[2] & ~SETTER_FLAG; + int val = get_esw(no); + if(val < 0) return ERR_BADPAR; + *(uint32_t*)&msg->data[4] = (uint32_t) val; FIXDL(msg); - *(uint32_t*)&msg->data[4] = getSwitches(no); return ERR_OK; } // bounce-free ESW get status -static errcodes esw(CAN_message *msg){ - uint8_t no = msg->data[2] & ~SETTER_FLAG; - if(no > 1) return ERR_BADPAR; +static errcodes eswg(CAN_message *msg){ + uint8_t no = INMAX+1; + if(msg->length > 2) no = msg->data[2] & ~SETTER_FLAG; + uint32_t curval = get_ab_esw(); + if(no > INMAX) *(uint32_t*)&msg->data[4] = curval; + else *(uint32_t*)&msg->data[4] = (curval & (1<data[4] = getESW(no); return ERR_OK; } -*/ // common uint32_t setter/getter static errcodes u32setget(CAN_message *msg){ @@ -131,7 +134,7 @@ static errcodes u32setget(CAN_message *msg){ uint32_t *ptr = NULL; switch(idx){ case CMD_CANSPEED: ptr = &the_conf.CANspeed; CAN_reinit(*(uint32_t*)&msg->data[4]); break; - //case CMD_BOUNCE: ptr = &the_conf.bounce_ms; break; + case CMD_BOUNCE: ptr = &the_conf.bouncetime; break; case CMD_USARTSPEED: ptr = &the_conf.usartspeed; break; default: break; } @@ -177,16 +180,16 @@ static const commonfunction funclist[CMD_AMOUNT] = { [CMD_TIME] = {time_getset, 0, 0, 0}, [CMD_MCUTEMP] = {mcut, 0, 0, 0}, [CMD_ADCRAW] = {adcraw, 0, 0, 3}, // need parno: 0..4 - [CMD_ADCV] = {adcv, 0, 0, 3}, // need parno: 0..3 [CMD_CANSPEED] = {u32setget, CAN_MIN_SPEED, CAN_MAX_SPEED, 0}, [CMD_CANID] = {canid, 1, 0x7ff, 0}, -// [CMD_ADCMUL] = {adcmul, 0, 0, 3}, // at least parno + [CMD_CANIDin] = {canidin, 1, 0x7ff, 0}, + [CMD_CANIDout] = {canidout, 1, 0x7ff, 0}, [CMD_SAVECONF] = {saveconf, 0, 0, 0}, [CMD_ERASESTOR] = {erasestor, 0, 0, 0}, -// [CMD_RELAY] = {relay, 0, 1, 0}, -// [CMD_GETESW_BLK] = {eswblk, 0, 0, 3}, -// [CMD_GETESW] = {esw, 0, 0, 3}, -// [CMD_BOUNCE] = {u32setget, 0, 300, 0}, + [CMD_RELAY] = {relay, 0, INT32_MAX, 0}, + [CMD_GETESW] = {eswg, 0, INT32_MAX, 0}, + [CMD_GETESWNOW] = {esw, 0, INT32_MAX, 0}, + [CMD_BOUNCE] = {u32setget, 0, 1000, 0}, [CMD_USARTSPEED] = {u32setget, 1200, 3000000, 0}, }; diff --git a/F1:F103/FX3U/canproto.h b/F1:F103/FX3U/canproto.h index e3604ff..557cdb2 100644 --- a/F1:F103/FX3U/canproto.h +++ b/F1:F103/FX3U/canproto.h @@ -45,29 +45,21 @@ typedef enum{ // CAN commands indexes enum{ - CMD_RESET, // 0 - reset MCU - CMD_TIME, // 1 - get/set Tms - CMD_MCUTEMP, // 2 - get MCU temperature (*10) - CMD_ADCRAW, // 3 - get ADC raw values - CMD_ADCV, // 4 - get ADC voltage (*100) - CMD_CANSPEED, // 5 - get/set CAN speed (kbps) - CMD_CANID, // 6 - get/set CAN ID - CMD_ADCMUL, // 7 - get/set ADC multipliers 0..4 - CMD_SAVECONF, // 8 - save configuration - CMD_ERASESTOR, // 9 - erase all flash storage - CMD_RELAY, // 10 - switch relay ON/OFF - CMD_GETESW_BLK, // 11 - blocking read of ESW - CMD_GETESW, // 12 - current ESW state, bounce-free - CMD_BOUNCE, // 13 - get/set bounce constant (ms) - CMD_USARTSPEED, // 14 - get/set USART1 speed (if encoder on RS-422) - CMD_ENCISSSI, // 15 - encoder is SSI (1) or RS-422 (0) - CMD_SPIINIT, // 16 - init SPI2 - CMD_SPISEND, // 17 - send 1..4 bytes over SPI - CMD_ENCGET, // 18 - get encoder value - CMD_EMULPEP, // 19 - emulate (1) / not (0) PEP - CMD_ENCREINIT, // 20 - reinit encoder - CMD_TIMESTAMP, // 21 - 2mks 24-bit timestamp - CMD_SPIDEINIT, // 22 - turn off SPI2 + CMD_RESET, // reset MCU + CMD_TIME, // get/set Tms + CMD_MCUTEMP, // get MCU temperature (*10) + CMD_ADCRAW, // get ADC raw values + CMD_CANSPEED, // get/set CAN speed (kbps) + CMD_CANID, // get/set common CAN ID (both in and out) + CMD_CANIDin, // input CAN ID + CMD_CANIDout, // output CAN ID + CMD_SAVECONF, // save configuration + CMD_ERASESTOR, // erase all flash storage + CMD_RELAY, // switch relay ON/OFF + CMD_GETESW, // current ESW state, bounce-free + CMD_GETESWNOW, // current ESW state, absolute + CMD_BOUNCE, // get/set bounce constant (ms) + CMD_USARTSPEED, // get/set USART1 speed (if encoder on RS-422) // should be the last: CMD_AMOUNT // amount of CAN commands }; diff --git a/F1:F103/FX3U/flash.c b/F1:F103/FX3U/flash.c index 5e74f87..41d9bd3 100644 --- a/F1:F103/FX3U/flash.c +++ b/F1:F103/FX3U/flash.c @@ -30,8 +30,10 @@ static uint32_t maxCnum = 1024 / sizeof(user_conf); // can't use blocksize here #define USERCONF_INITIALIZER { \ .userconf_sz = sizeof(user_conf) \ ,.CANspeed = 250000 \ - ,.CANID = 1 \ + ,.CANIDin = 1 \ + ,.CANIDout = 2 \ ,.usartspeed = 115200 \ + ,.bouncetime = 50 \ } static int write2flash(const void*, const void*, uint32_t); diff --git a/F1:F103/FX3U/flash.h b/F1:F103/FX3U/flash.h index f64db19..2238c8c 100644 --- a/F1:F103/FX3U/flash.h +++ b/F1:F103/FX3U/flash.h @@ -28,7 +28,10 @@ */ typedef struct __attribute__((aligned(4))){ uint16_t userconf_sz; // "magick number" - uint16_t CANID; // CAN bus device ID + uint16_t CANIDin; // CAN bus device ID for input commands + uint16_t CANIDout; // -//- for output signals + uint16_t reserved; + uint32_t bouncetime; // anti-bounce timeout (ms) uint32_t usartspeed; // RS-232 speed uint32_t CANspeed; // CAN bus speed } user_conf; diff --git a/F1:F103/FX3U/fx3u.bin b/F1:F103/FX3U/fx3u.bin index 96485bfd92a69939b962a48901181b7675e08dda..1d624e122723e4d63ed4eaea9b91757a35208565 100755 GIT binary patch delta 6243 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 Nn7dhz$sZfY{{lXvyK(>k diff --git a/F1:F103/FX3U/fx3u.creator.user b/F1:F103/FX3U/fx3u.creator.user index f3e42e0..2796bd3 100644 --- a/F1:F103/FX3U/fx3u.creator.user +++ b/F1:F103/FX3U/fx3u.creator.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/F1:F103/FX3U/hardware.c b/F1:F103/FX3U/hardware.c index 6b0a98f..1d1e6cd 100644 --- a/F1:F103/FX3U/hardware.c +++ b/F1:F103/FX3U/hardware.c @@ -16,7 +16,13 @@ * along with this program. If not, see . */ +#include "can.h" +#include "canproto.h" +#include "flash.h" #include "hardware.h" +#ifdef EBUG +#include "strfunc.h" +#endif /* pinout: @@ -103,3 +109,145 @@ void iwdg_setup(){ while(IWDG->SR){if(--tmout == 0) break;} IWDG->KR = IWDG_REFRESH; } + +typedef struct{ + GPIO_TypeDef* port; // GPIOx or NULL if no such pin + uint16_t pin; // (1 << pin) +} pin_t; + +// input pins (X0..X15) +static const pin_t IN[INMAX+1] = { // youbannye uskoglazye pidarasy! Ready to fuck their own mother to save kopeyka + {GPIOB, 1<<13}, // X0 - PB13 + {GPIOB, 1<<14}, // X1 - PB14 + {GPIOB, 1<<11}, // X2 - PB11 + {GPIOB, 1<<12}, // X3 - PB12 + {GPIOE, 1<<15}, // X4 - PE15 + {GPIOB, 1<<10}, // X5 - PB10 + {GPIOE, 1<<13}, // X6 - PE13 + {GPIOE, 1<<14}, // X7 - PE14 + {NULL, 0}, // X8 - absent + {NULL, 0}, // X9 - absent + {GPIOE, 1<11}, // X10 - PE11 + {GPIOE, 1<<12}, // X11 - PE12 + {GPIOE, 1<<9}, // X12 - PE9 + {GPIOE, 1<<10}, // X13 - PE10 + {GPIOE, 1<<7}, // X14 - PE7 + {GPIOE, 1<<8}, // X15 - PE8 +}; + +// output (relay) pins (Y0..Y15) +static const pin_t OUT[OUTMAX+1] = { + {GPIOC, 1<<9}, // Y0 - PC9 + {GPIOC, 1<<8}, // Y1 - PC8 + {GPIOA, 1<<8}, // Y2 - PA8 + {GPIOA, 1<<0}, // Y3 - PA0 + {GPIOB, 1<<3}, // Y4 - PB3 + {GPIOD, 1<<12}, // Y5 - PD12 + {GPIOB, 1<<15}, // Y6 - PB15 + {GPIOA, 1<<7}, // Y7 - PA7 + {NULL, 0}, // Y8 - absent + {NULL, 0}, // Y9 - absent + {GPIOA, 1<<6}, // Y10 - PA6 + {GPIOA, 1<<2}, // Y11 - PA2 +}; + +// bit 1 - input channel is working, 0 - no +uint32_t inchannels(){ + return 0b1111110011111111; +} +// bit 1 - input channel is working, 0 - no +uint32_t outchannels(){ + return 0b110011111111; +} + +/** + * @brief set_relay - turn on/off relay `Nch` (if Nch > OUTMAX - all) + * @param Nch - single relay channel No or >Ymax to set/reset all relays + * @param val - value to set/reset/change + * @return TRUE if OK, -1 if `Nch` is wrong + */ +int set_relay(uint8_t Nch, uint32_t val){ + int chpin(uint8_t N, uint32_t v){ + const pin_t *cur = &OUT[N]; + if(NULL == cur->port) return -1; + if(v) pin_set(cur->port, cur->pin); + else pin_clear(cur->port, cur->pin); + return TRUE; + } + if(Nch > OUTMAX){ // all + uint32_t mask = 1; + for(uint8_t i = 0; i <= OUTMAX; ++i, mask <<= 1){ + chpin(i, val & mask); + } + return TRUE; + } + return chpin(Nch, val); +} + +static int readpins(uint8_t Nch, const pin_t *pins, uint8_t max){ + int gpin(uint8_t N){ + const pin_t *cur = &pins[N]; + if(NULL == cur->port) return -1; + return pin_read(cur->port, cur->pin); + } + if(Nch > max){ // all + int val = 0; + for(int i = max; i > -1; --i){ + val <<= 1; + int p = gpin(i); + if(p > -1) val |= gpin(i); + } +usart_send("readpins, val="); usart_send(i2str(val)); newline(); + return val; + } + return gpin(Nch); +} + +/** + * @brief get_relay - get `Nch` relay state (if Nch > OUTMAX - all) + * @param Nch - single relay channel No or <0 for all + * @return current state or -1 if `Nch` is wrong + */ +int get_relay(uint8_t Nch){ + return readpins(Nch, OUT, OUTMAX); +} + +/** + * @brief get_esw - get input `Nch` state (or all if Nch > INMAX) + * @param Nch - channel number or -1 for all + * @return ESW state or -1 if `Nch` is wrong + */ +int get_esw(uint8_t Nch){ + return readpins(Nch, IN, INMAX); +} + +static uint32_t ESW_ab_values = 0; // current anti-bounce values of ESW +static uint32_t lastET[INMAX+1] = {0}; // last changing time + +// anti-bouce process esw +void proc_esw(){ + uint32_t mask = 1, oldesw = ESW_ab_values; + for(uint8_t i = 0; i <= OUTMAX; ++i, mask <<= 1){ + if(Tms - lastET[i] < the_conf.bouncetime) continue; + if(NULL == IN[i].port) continue; + uint32_t now = pin_read(IN[i].port, IN[i].pin); + if(now) ESW_ab_values |= mask; + else ESW_ab_values &= ~mask; + lastET[i] = Tms; + } + if(oldesw != ESW_ab_values){ + usart_send("esw="); usart_send(u2str(ESW_ab_values)); newline(); + CAN_message msg = {.ID = the_conf.CANIDout, .length = 8}; + msg.data[0] = CMD_GETESW; + *((uint32_t*)(&msg.data[4])) = ESW_ab_values; + uint32_t Tstart = Tms; + while(Tms - Tstart < SEND_TIMEOUT_MS){ + if(CAN_OK == CAN_send(&msg)) return; + } + } +} + +// get all anti-bounce ESW values +uint32_t get_ab_esw(){ + return ESW_ab_values; +} diff --git a/F1:F103/FX3U/hardware.h b/F1:F103/FX3U/hardware.h index d90dcec..2024f45 100644 --- a/F1:F103/FX3U/hardware.h +++ b/F1:F103/FX3U/hardware.h @@ -20,14 +20,32 @@ #include + #define CONCAT(a,b) a ## b #define STR_HELPER(s) #s #define STR(s) STR_HELPER(s) +/* this stuff may be usefull later #define FORMUSART(X) CONCAT(USART, X) #define USARTX FORMUSART(USARTNUM) +*/ + +// max number of in/out pins +#define INMAX (15) +#define OUTMAX (11) extern volatile uint32_t Tms; void gpio_setup(void); void iwdg_setup(); +int set_relay(uint8_t Nch, uint32_t val); +int get_relay(uint8_t Nch); +int get_esw(uint8_t Nch); +void proc_esw(); +uint32_t get_ab_esw(); + +uint32_t inchannels(); +uint32_t outchannels(); +int set_relay(uint8_t Nch, uint32_t val); +int get_relay(uint8_t Nch); +int get_esw(uint8_t Nch); diff --git a/F1:F103/FX3U/main.c b/F1:F103/FX3U/main.c index 0b38cb5..1ce3a98 100644 --- a/F1:F103/FX3U/main.c +++ b/F1:F103/FX3U/main.c @@ -51,6 +51,7 @@ int main(void){ usart_transmit(); lastT = Tms; } + proc_esw(); CAN_proc(); CAN_status st = CAN_get_status(); if(st == CAN_FIFO_OVERRUN){ diff --git a/F1:F103/FX3U/proto.c b/F1:F103/FX3U/proto.c index fee514c..14d12a9 100644 --- a/F1:F103/FX3U/proto.c +++ b/F1:F103/FX3U/proto.c @@ -53,20 +53,28 @@ static const funcdescr funclist[] = { // {"adcraw", CMD_ADCRAW, "get raw ADC values of channel 0..4"}, // {"adcv", CMD_ADCV, "get ADC voltage of channel 0..3 (*100V)"}, // {"bounce", CMD_BOUNCE, "get/set bounce constant (ms)"}, + {NULL, 0, "CAN bus commands"}, {"canbuserr", -TCMD_CANBUSERRPRNT, "print all CAN bus errors (a lot of if not connected)"}, - {"canid", CMD_CANID, "get/set CAN ID"}, {"cansniff", -TCMD_CANSNIFFER, "switch CAN sniffer mode"}, + {NULL, 0, "Configuration"}, + {"bounce", CMD_BOUNCE, "set/get anti-bounce timeout (ms, max: 1000)"}, + {"canid", CMD_CANID, "set both (in/out) CAN ID / get in CAN ID"}, + {"canidin", CMD_CANIDin, "get/set input CAN ID"}, + {"canidout", CMD_CANIDout, "get/set output CAN ID"}, {"canspeed", CMD_CANSPEED, "get/set CAN speed (bps)"}, {"dumpconf", -TCMD_DUMPCONF, "dump current configuration"}, - {"esw", CMD_GETESW, "anti-bounce read ESW of channel 0 or 1"}, {"eraseflash", CMD_ERASESTOR, "erase all flash storage"}, - {"mcutemp", CMD_MCUTEMP, "get MCU temperature (*10degrC)"}, + {"saveconf", CMD_SAVECONF, "save configuration"}, + {"usartspeed", CMD_USARTSPEED, "get/set USART1 speed"}, + {NULL, 0, "IN/OUT"}, + {"esw", CMD_GETESW, "anti-bounce read inputs"}, + {"eswnow", CMD_GETESWNOW, "read current inputs' state"}, {"relay", CMD_RELAY, "get/set relay state (0 - off, 1 - on)"}, + {NULL, 0, "Other commands"}, + {"mcutemp", CMD_MCUTEMP, "get MCU temperature (*10degrC)"}, {"reset", CMD_RESET, "reset MCU"}, {"s", -TCMD_CANSEND, "send CAN message: ID 0..8 data bytes"}, - {"saveconf", CMD_SAVECONF, "save configuration"}, {"time", CMD_TIME, "get/set time (1ms, 32bit)"}, - {"usartspeed", CMD_USARTSPEED, "get/set USART1 speed"}, {"wdtest", -TCMD_WDTEST, "test watchdog"}, {NULL, 0, NULL} // last record }; @@ -150,12 +158,14 @@ static errcodes dumpconf(const char _U_ *str){ usart_send("\nuserconf_idx="); printi(currentconfidx); usart_send("\nuserconf_sz="); printu(the_conf.userconf_sz); usart_send("\ncanspeed="); printu(the_conf.CANspeed); - usart_send("\ncanid="); printu(the_conf.CANID); + usart_send("\ncanid_in="); printu(the_conf.CANIDin); + usart_send("\ncanid_out="); printu(the_conf.CANIDout); /*for(int i = 0; i < ADC_TSENS; ++i){ usart_send("\nadcmul"); usart_putchar('0'+i); usart_putchar('='); usart_send(float2str(the_conf.adcmul[i], 3)); }*/ usart_send("\nusartspeed="); printu(the_conf.usartspeed); + usart_send("\nbouncetime="); printu(the_conf.bouncetime); /* const char * const *p = bitfields; int bit = 0; @@ -254,8 +264,7 @@ void cmd_parser(const char *str){ if(l == 0) goto ret; cmd[l] = 0; while(c->help){ - if(!c->cmd) continue; - if(0 == strcmp(c->cmd, cmd)){ + if(c->cmd && 0 == strcmp(c->cmd, cmd)){ idx = c->idx; break; } diff --git a/F1:F103/FX3U/strfunc.h b/F1:F103/FX3U/strfunc.h index 0d0b72d..d7ceeb1 100644 --- a/F1:F103/FX3U/strfunc.h +++ b/F1:F103/FX3U/strfunc.h @@ -21,6 +21,7 @@ #include #include +#include "hardware.h" #include "usart.h" #ifndef _U_ diff --git a/F1:F103/FX3U/version.inc b/F1:F103/FX3U/version.inc index a4d3b7e..144ca8b 100644 --- a/F1:F103/FX3U/version.inc +++ b/F1:F103/FX3U/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "36" -#define BUILD_DATE "2024-06-01" +#define BUILD_NUMBER "50" +#define BUILD_DATE "2024-06-03" diff --git a/F1:F103/inc/ld/stm32f103xC.ld b/F1:F103/inc/ld/stm32f103xC.ld index 9a27c5b..c263bd2 100644 --- a/F1:F103/inc/ld/stm32f103xC.ld +++ b/F1:F103/inc/ld/stm32f103xC.ld @@ -26,7 +26,7 @@ MEMORY ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K } -PROVIDE(_BLOCKSIZE = 1024); +PROVIDE(_BLOCKSIZE = 2048); /* Include the common ld script. */ INCLUDE stm32f01234.ld diff --git a/F1:F103/inc/ld/stm32f103xD.ld b/F1:F103/inc/ld/stm32f103xD.ld index 923910c..9e0da7a 100644 --- a/F1:F103/inc/ld/stm32f103xD.ld +++ b/F1:F103/inc/ld/stm32f103xD.ld @@ -26,7 +26,7 @@ MEMORY ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K } -PROVIDE(_BLOCKSIZE = 1024); +PROVIDE(_BLOCKSIZE = 2048); /* Include the common ld script. */ INCLUDE stm32f01234.ld diff --git a/F1:F103/inc/ld/stm32f103xE.ld b/F1:F103/inc/ld/stm32f103xE.ld index da143de..8947f36 100644 --- a/F1:F103/inc/ld/stm32f103xE.ld +++ b/F1:F103/inc/ld/stm32f103xE.ld @@ -26,7 +26,7 @@ MEMORY ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K } -PROVIDE(_BLOCKSIZE = 1024); +PROVIDE(_BLOCKSIZE = 2048); /* Include the common ld script. */ INCLUDE stm32f01234.ld diff --git a/F1:F103/inc/ld/stm32f103xF.ld b/F1:F103/inc/ld/stm32f103xF.ld index 2a52a01..77ef2cd 100644 --- a/F1:F103/inc/ld/stm32f103xF.ld +++ b/F1:F103/inc/ld/stm32f103xF.ld @@ -26,7 +26,7 @@ MEMORY ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K } -PROVIDE(_BLOCKSIZE = 1024); +PROVIDE(_BLOCKSIZE = 2048); /* Include the common ld script. */ INCLUDE stm32f01234.ld diff --git a/F1:F103/inc/ld/stm32f103xG.ld b/F1:F103/inc/ld/stm32f103xG.ld index 5fd0095..2424a56 100644 --- a/F1:F103/inc/ld/stm32f103xG.ld +++ b/F1:F103/inc/ld/stm32f103xG.ld @@ -26,7 +26,7 @@ MEMORY ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K } -PROVIDE(_BLOCKSIZE = 1024); +PROVIDE(_BLOCKSIZE = 2048); /* Include the common ld script. */ INCLUDE stm32f01234.ld