From 01f6187229d351c2b4587d3576c52c79652a626c Mon Sep 17 00:00:00 2001 From: Edward Emelianov Date: Mon, 8 Jan 2024 22:46:25 +0300 Subject: [PATCH] add end-switches management --- F3:F303/CANbus4BTA/BTA_CAN.bin | Bin 19732 -> 21176 bytes F3:F303/CANbus4BTA/can.c | 15 ++- F3:F303/CANbus4BTA/canbus4bta.creator.user | 2 +- F3:F303/CANbus4BTA/canbus4bta.files | 2 + F3:F303/CANbus4BTA/commonfunctions.c | 39 +++++++- F3:F303/CANbus4BTA/flash.c | 1 + F3:F303/CANbus4BTA/flash.h | 1 + F3:F303/CANbus4BTA/gpio.c | 102 +++++++++++++++++++++ F3:F303/CANbus4BTA/gpio.h | 24 +++++ F3:F303/CANbus4BTA/hardware.c | 4 +- F3:F303/CANbus4BTA/hardware.h | 14 +++ F3:F303/CANbus4BTA/main.c | 12 +++ F3:F303/CANbus4BTA/proto.h | 4 + F3:F303/CANbus4BTA/textfunctions.c | 6 +- F3:F303/CANbus4BTA/version.inc | 2 +- 15 files changed, 220 insertions(+), 8 deletions(-) create mode 100644 F3:F303/CANbus4BTA/gpio.c create mode 100644 F3:F303/CANbus4BTA/gpio.h diff --git a/F3:F303/CANbus4BTA/BTA_CAN.bin b/F3:F303/CANbus4BTA/BTA_CAN.bin index c030ba80fbb1659aa127b3a88467eed46c6285d6..1f55b850a1731793a725c11e641c01ec237a489e 100755 GIT binary patch delta 5500 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 F`X6*YgfsvE diff --git a/F3:F303/CANbus4BTA/can.c b/F3:F303/CANbus4BTA/can.c index 3be9089..94cec5e 100644 --- a/F3:F303/CANbus4BTA/can.c +++ b/F3:F303/CANbus4BTA/can.c @@ -32,6 +32,15 @@ #include // memcpy +// CAN bus oscillator frequency: 36MHz +#define CAN_F_OSC (36000000UL) +// timing values TBS1 and TBS2 (in BTR [TBS1-1] and [TBS2-1]) +// use 3 and 2 to get 6MHz +#define CAN_TBS1 (3) +#define CAN_TBS2 (2) +// bitrate oscillator frequency +#define CAN_BIT_OSC (CAN_F_OSC / (1+CAN_TBS1+CAN_TBS2)) + uint8_t cansniffer = 0; // 0 - receive only 0 and myID, 1 - receive all // circular buffer for received messages @@ -143,7 +152,7 @@ void CAN_setup(uint32_t speed){ /* (1) Enter CAN init mode to write the configuration */ /* (2) Wait the init mode entering */ /* (3) Exit sleep mode */ - /* (4) Normal mode, set timing to 100kb/s: TBS1 = 4, TBS2 = 3, prescaler = 60 */ + /* (4) Normal mode, set timing : TBS1 = 4, TBS2 = 3 */ /* (5) Leave init mode */ /* (6) Wait the init mode leaving */ /* (7) Enter filter init mode, (16-bit + mask, bank 0 for FIFO 0) */ @@ -158,8 +167,8 @@ void CAN_setup(uint32_t speed){ if(tmout==0){ DBG("timeout!\n");} CAN->MCR &=~ CAN_MCR_SLEEP; /* (3) */ CAN->MCR |= CAN_MCR_ABOM; /* allow automatically bus-off */ - CAN->BTR = 2 << 20 | 3 << 16 | (((uint32_t)4500000UL)/speed - 1); //| CAN_BTR_SILM | CAN_BTR_LBKM; /* (4) */ - oldspeed = ((uint32_t)4500000UL)/(uint32_t)((CAN->BTR & CAN_BTR_BRP) + 1); + CAN->BTR = (CAN_TBS2-1) << 20 | (CAN_TBS1-1) << 16 | (CAN_BIT_OSC/speed - 1); //| CAN_BTR_SILM | CAN_BTR_LBKM; /* (4) */ + oldspeed = CAN_BIT_OSC/(uint32_t)((CAN->BTR & CAN_BTR_BRP) + 1); CAN->MCR &= ~CAN_MCR_INRQ; /* (5) */ tmout = 10000; while(CAN->MSR & CAN_MSR_INAK) /* (6) */ diff --git a/F3:F303/CANbus4BTA/canbus4bta.creator.user b/F3:F303/CANbus4BTA/canbus4bta.creator.user index 332da69..b114d45 100644 --- a/F3:F303/CANbus4BTA/canbus4bta.creator.user +++ b/F3:F303/CANbus4BTA/canbus4bta.creator.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/F3:F303/CANbus4BTA/canbus4bta.files b/F3:F303/CANbus4BTA/canbus4bta.files index 9930bb6..4478816 100644 --- a/F3:F303/CANbus4BTA/canbus4bta.files +++ b/F3:F303/CANbus4BTA/canbus4bta.files @@ -6,6 +6,8 @@ commonfunctions.c commonfunctions.h flash.c flash.h +gpio.c +gpio.h hardware.c hardware.h main.c diff --git a/F3:F303/CANbus4BTA/commonfunctions.c b/F3:F303/CANbus4BTA/commonfunctions.c index 46dd599..f4a828c 100644 --- a/F3:F303/CANbus4BTA/commonfunctions.c +++ b/F3:F303/CANbus4BTA/commonfunctions.c @@ -20,6 +20,7 @@ #include "can.h" #include "commonfunctions.h" #include "flash.h" +#include "gpio.h" #include "proto.h" #include "usb.h" @@ -102,7 +103,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){ + if(ISSETTER(msg->data)){ + if(msg->data[4] == 1) RELAY_ON(); + else RELAY_OFF(); + }else FIXDL(msg); + *(uint32_t*)&msg->data[4] = RELAY_GET(); + 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; + 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; + FIXDL(msg); + *(uint32_t*)&msg->data[4] = getESW(no); + return ERR_OK; +} +// bounce constant, ms +static errcodes bounce(CAN_message *msg){ + if(ISSETTER(msg->data)){ + the_conf.bounce_ms = *(uint32_t*)&msg->data[4]; + }else FIXDL(msg); + *(uint32_t*)&msg->data[4] = the_conf.bounce_ms; + return ERR_OK; +} /************ END of all common functions list (for `funclist`) ************/ @@ -126,6 +159,10 @@ static const commonfunction funclist[CMD_AMOUNT] = { [CMD_ADCMUL] = {adcmul, 0, 0, 3}, // at least parno [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] = {bounce, 0, 300, 0}, }; diff --git a/F3:F303/CANbus4BTA/flash.c b/F3:F303/CANbus4BTA/flash.c index d4366f8..5976917 100644 --- a/F3:F303/CANbus4BTA/flash.c +++ b/F3:F303/CANbus4BTA/flash.c @@ -35,6 +35,7 @@ static uint32_t maxCnum = 1024 / sizeof(user_conf); // can't use blocksize here .userconf_sz = sizeof(user_conf) \ ,.CANspeed = 100000 \ ,.CANID = 0xaa \ + ,.bounce = 50 \ ,.adcmul[0] = 10.930f \ ,.adcmul[1] = 2.028f \ ,.adcmul[2] = 1.f \ diff --git a/F3:F303/CANbus4BTA/flash.h b/F3:F303/CANbus4BTA/flash.h index 5e1b871..4f5730f 100644 --- a/F3:F303/CANbus4BTA/flash.h +++ b/F3:F303/CANbus4BTA/flash.h @@ -35,6 +35,7 @@ typedef struct __attribute__((packed, aligned(4))){ uint16_t userconf_sz; // "magick number" uint16_t CANID; // identifier uint32_t CANspeed; // default CAN speed + uint32_t bounce_ms; // a float adcmul[ADC_TSENS]; // ADC voltage multipliers } user_conf; diff --git a/F3:F303/CANbus4BTA/gpio.c b/F3:F303/CANbus4BTA/gpio.c new file mode 100644 index 0000000..acc15a0 --- /dev/null +++ b/F3:F303/CANbus4BTA/gpio.c @@ -0,0 +1,102 @@ +/* + * This file is part of the canbus4bta project. + * Copyright 2024 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 "flash.h" +#include "gpio.h" +#include "hardware.h" + +// GPIO IN management by two 74HC4051 + +static uint8_t eswitches[2] = {0}; +static uint8_t stage = 0; +static uint32_t lastT[8][2] = {0}; // last time of ESW changed + +uint8_t getESW(uint8_t nch){ + return eswitches[nch]; +} + +// update `eswitches`, anti-bounce +TRUE_INLINE void updesw(uint8_t nch, uint8_t newval){ + uint8_t mask = eswitches[nch] ^ newval, newmask = 0; + if(mask == 0) return; + for(uint8_t bit = 0; bit < 8; ++bit){ // check all bits of mask + newmask >>= 1; + if((mask & 1) && Tms - lastT[bit][nch] >= the_conf.bounce_ms){ // OK, change this value + newmask |= 0x80; + lastT[bit][nch] = Tms; + } + mask >>= 1; + } + if(newmask == 0) return; + // now change only allowable bits + eswitches[nch] = (eswitches[nch] & ~newmask) | (newval & newmask); +} + +/** + * @brief ESW_process - process multiplexer 1 + */ +void ESW_process(){ + static uint8_t curch = 0; + static int curaddr = 7; + static uint8_t ESW = 0; + switch(stage){ + case 0: // stage 0: change address and turn on multiplexer + stage = 1; + MULADDR_set(curaddr); + MUL_ON(curch); + break; + case 1: // stage 1: read data and turn off mul + default: + stage = 0; + ESW <<= 1; + ESW |= ESW_GET(); + MUL_OFF(curch); + if(--curaddr < 0){ + updesw(curch, ESW); + curch = !curch; + curaddr = 7; + } + break; + } +} + +static void NeverDoThisFuckingShit(){ + uint32_t ctr = 3; + while(ctr--) nop(); +} + +/** + * @brief getSwitches - blocking read of all switches of given channel + * @param chno - number of multiplexer: 0 (board switches) or 1 (external ESW) + */ +uint8_t getSwitches(uint8_t chno){ + if(chno > 1) return 0; + MUL_OFF(0); MUL_OFF(1); + uint8_t state = 0; + for(int i = 7; i > -1; --i){ + MULADDR_set(i); + MUL_ON(chno); + state <<= 1; + NeverDoThisFuckingShit(); + state |= ESW_GET(); + MUL_OFF(chno); + NeverDoThisFuckingShit(); + } + stage = 0; // prevent interference with `ESW_process()` + return state; +} diff --git a/F3:F303/CANbus4BTA/gpio.h b/F3:F303/CANbus4BTA/gpio.h new file mode 100644 index 0000000..2b63608 --- /dev/null +++ b/F3:F303/CANbus4BTA/gpio.h @@ -0,0 +1,24 @@ +/* + * This file is part of the canbus4bta project. + * Copyright 2024 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 +#include + +uint8_t getESW(uint8_t nch); +void ESW_process(); +uint8_t getSwitches(uint8_t chno); diff --git a/F3:F303/CANbus4BTA/hardware.c b/F3:F303/CANbus4BTA/hardware.c index fa04be3..2836d52 100644 --- a/F3:F303/CANbus4BTA/hardware.c +++ b/F3:F303/CANbus4BTA/hardware.c @@ -47,6 +47,7 @@ TRUE_INLINE void iwdg_setup(){ #endif static inline void gpio_setup(){ + RELAY_OFF(); MUL_OFF(0); MUL_OFF(1); RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOCEN; // PWM - AF1 @PA7; USB - alternate function 14 @ pins PA11/PA12; USART1 = AF7 @PA9/10; SWD - AF0 @PA13/14 GPIOA->AFR[0] = AFRf(1, 7); @@ -57,7 +58,8 @@ static inline void gpio_setup(){ GPIOA->MODER = MODER_AI(0) | MODER_AI(1) | MODER_AI(2) | MODER_AI(3) | MODER_I(4) | MODER_O(5) | MODER_O(6) | MODER_AF(7) | MODER_I(8) | MODER_AF(9) | MODER_AF(10) | MODER_AF(11) | MODER_AF(12) | MODER_AF(13) | MODER_AF(14) | MODER_I(15); - GPIOA->OSPEEDR = OSPEED_MED(7) | OSPEED_MED(9) | OSPEED_MED(10) | OSPEED_HI(11) | OSPEED_HI(12) | OSPEED_HI(13) | OSPEED_HI(14); + GPIOA->OSPEEDR = OSPEED_HI(4) | OSPEED_MED(7) | OSPEED_MED(9) | OSPEED_MED(10) | OSPEED_HI(11) | + OSPEED_HI(12) | OSPEED_HI(13) | OSPEED_HI(14); // SPI for SSI: AF5 @PB3, PB4; I2C1: AF4 @PB6, PB7; CAN: AF9 @PB8, PB9; SPI2: AF5 @PB12..PB15 GPIOB->AFR[0] = AFRf(5, 3) | AFRf(5, 4) | AFRf(4, 6) | AFRf(4, 7); GPIOB->AFR[1] = AFRf(9, 8) | AFRf(9, 9) | AFRf(5, 12) | AFRf(5, 13) | AFRf(5, 14) | AFRf(5, 15); diff --git a/F3:F303/CANbus4BTA/hardware.h b/F3:F303/CANbus4BTA/hardware.h index a623393..c1138cf 100644 --- a/F3:F303/CANbus4BTA/hardware.h +++ b/F3:F303/CANbus4BTA/hardware.h @@ -20,11 +20,25 @@ #include +// USB pullup #define USBPU_port GPIOC #define USBPU_pin (1<<15) #define USBPU_ON() pin_set(USBPU_port, USBPU_pin) #define USBPU_OFF() pin_clear(USBPU_port, USBPU_pin) +// relay +#define RELAY_port GPIOC +#define RELAY_pin (1<<14) +#define RELAY_ON() pin_set(RELAY_port, RELAY_pin) +#define RELAY_OFF() pin_clear(RELAY_port, RELAY_pin) +#define RELAY_GET() pin_read(RELAY_port, RELAY_pin) + +// GPIO end-switches multiplexer (addr - PB0..2, ~DEN0 - PA5, ~DEN1 - PA6) and input (PA4) +#define ESW_GET() (GPIOA->IDR & (1<<4) ? 0 : 1) +#define MULADDR_set(x) do{GPIOB->BSRR = (x&7) | (((~x)&7) << 16);}while(0) +#define MUL_ON(x) pin_clear(GPIOA, 1<<(5+x)) +#define MUL_OFF(x) pin_set(GPIOA, 1<<(5+x)) + extern volatile uint32_t Tms; void hw_setup(); diff --git a/F3:F303/CANbus4BTA/main.c b/F3:F303/CANbus4BTA/main.c index 4263c36..91aaeb8 100644 --- a/F3:F303/CANbus4BTA/main.c +++ b/F3:F303/CANbus4BTA/main.c @@ -18,6 +18,7 @@ #include "can.h" #include "flash.h" +#include "gpio.h" #include "hardware.h" #include "textfunctions.h" #include "usart.h" @@ -57,6 +58,7 @@ int main(void){ } flashstorage_init(); hw_setup(); + // getSwitches() and set module role & CAN ID CAN_setup(the_conf.CANspeed); USBPU_ON(); while(1){ @@ -86,5 +88,15 @@ int main(void){ const char *ans = run_text_cmd(inbuff); if(ans) USB_sendstr(ans); } + ESW_process(); + static uint8_t oldswitches[2] = {0}; + for(int i = 0; i < 2; ++i){ + uint8_t new = getESW(i); + if(oldswitches[i] != new){ + oldswitches[i] = new; + USB_sendstr("ESW changed @"); printu(Tms); + USB_sendstr(" to "); printuhex(new); newline(); + } + } } } diff --git a/F3:F303/CANbus4BTA/proto.h b/F3:F303/CANbus4BTA/proto.h index 5981ff8..677c4f9 100644 --- a/F3:F303/CANbus4BTA/proto.h +++ b/F3:F303/CANbus4BTA/proto.h @@ -60,6 +60,10 @@ typedef enum{ 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_AMOUNT // amount of CAN commands } can_cmd; diff --git a/F3:F303/CANbus4BTA/textfunctions.c b/F3:F303/CANbus4BTA/textfunctions.c index aff6ac3..d1615e4 100644 --- a/F3:F303/CANbus4BTA/textfunctions.c +++ b/F3:F303/CANbus4BTA/textfunctions.c @@ -53,12 +53,16 @@ static const funcdescr funclist[] = { {"adcmul", CMD_ADCMUL, "get/set ADC multipliers 0..3 (*1000)"}, {"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)"}, {"canid", CMD_CANID, "get/set CAN ID"}, {"cansnif", -TCMD_CANSNIF, "get/change sniffer state (0 - normal, 1 - sniffer)"}, {"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"}, + {"eswblk", CMD_GETESW_BLK, "blocking read ESW of channel 0 or 1"}, {"eraseflash", CMD_ERASESTOR, "erase all flash storage"}, {"mcutemp", CMD_MCUTEMP, "get MCU temperature (*10degrC)"}, + {"relay", CMD_RELAY, "get/set relay state (0 - off, 1 - on)"}, {"reset", CMD_RESET, "reset MCU"}, {"s", -TCMD_CANSEND, "send CAN message: ID 0..8 data bytes"}, {"saveconf", CMD_SAVECONF, "save configuration"}, @@ -144,7 +148,7 @@ static errcodes cansend(const char *txt){ uint32_t Tstart = Tms; while(Tms - Tstart < SEND_TIMEOUT_MS){ if(CAN_OK == CAN_send(&canmsg)){ - USB_sendstr("OK\n"); + //USB_sendstr("OK\n"); - don't send OK, as after sending might be an error return ERR_OK; } } diff --git a/F3:F303/CANbus4BTA/version.inc b/F3:F303/CANbus4BTA/version.inc index c14b316..7893c4b 100644 --- a/F3:F303/CANbus4BTA/version.inc +++ b/F3:F303/CANbus4BTA/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "56" +#define BUILD_NUMBER "68" #define BUILD_DATE "2024-01-08"