From bc82142e87fa004c73263750177b74a94ffb1113 Mon Sep 17 00:00:00 2001 From: Edward Emelianov Date: Fri, 8 Mar 2024 13:23:23 +0300 Subject: [PATCH] PEP emulation (didn't test yet) --- F3:F303/CANbus4BTA/BTA_CAN.bin | Bin 22900 -> 23572 bytes F3:F303/CANbus4BTA/Readme.md | 53 +++++++++++++++++++++++++++ F3:F303/CANbus4BTA/commonfunctions.c | 16 ++++++++ F3:F303/CANbus4BTA/encoder.c | 31 +++++++++++++++- F3:F303/CANbus4BTA/encoder.h | 2 + F3:F303/CANbus4BTA/flash.c | 4 +- F3:F303/CANbus4BTA/flash.h | 4 ++ F3:F303/CANbus4BTA/hardware.c | 13 ++++++- F3:F303/CANbus4BTA/hardware.h | 3 ++ F3:F303/CANbus4BTA/main.c | 21 ++++++----- F3:F303/CANbus4BTA/proto.h | 3 ++ F3:F303/CANbus4BTA/spi.c | 30 ++++++++++++--- F3:F303/CANbus4BTA/spi.h | 1 + F3:F303/CANbus4BTA/textfunctions.c | 9 ++++- F3:F303/CANbus4BTA/usart.c | 12 +++++- F3:F303/CANbus4BTA/usart.h | 3 +- F3:F303/CANbus4BTA/version.inc | 4 +- 17 files changed, 183 insertions(+), 26 deletions(-) diff --git a/F3:F303/CANbus4BTA/BTA_CAN.bin b/F3:F303/CANbus4BTA/BTA_CAN.bin index 53faf23deb61405ebddaa3e8981fdbe64260c88c..ca204794176c40d74aaf33dddf83be41f7fc3892 100755 GIT binary patch delta 6692 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 diff --git a/F3:F303/CANbus4BTA/Readme.md b/F3:F303/CANbus4BTA/Readme.md index 9c3c277..a33949a 100644 --- a/F3:F303/CANbus4BTA/Readme.md +++ b/F3:F303/CANbus4BTA/Readme.md @@ -122,6 +122,59 @@ Channel1 - ADC1. ## DMA2 +# Other resources usage +## Timers + +- SysTick is 1ms system time counter (`Tms`). +- TIM2 is 32bit timer with 2mks period (system timestamp for PEP emulation). + +## CAN + +CAN bus is primary interface. + +## USB + +USB (PL2303 emulation with iINTERFACE="canbusbta") used as alternate managing interface and for debugging. + +## USART + +USART1 can be used to operate with external encoder or other device over RS-422. + +## SPI + +- SPI1 used to work with external SSI encoder. +- SPI2 used with some external things. + +## I2C + +not implemented yet + +## ADC + +ADC1 used to measure internal temperature (CH16) and external: + +- CH1 - external power supply (raw value approx Uext/10). +- CH2 - onboard 5V supply after DC-DC (raw value approx V/2). +- CH3, CH4 - external inputs through dividers on RV1/R14 and RV2/R15. + +## GPIO + +GPIOA: + +- PA4 - DIN - input of multiplexers U1 and U2. +- PA5 - DEN0 - enable multiplexer U1. +- PA6 - DEN1 - enable multiplexer U2. + +GPIOB: + +- PB0..PB2 - 3bit input address on multiplexer. + +GPIOC: + +- PC13 - buzzer (not implemented yet). +- PC14 - relay. +- PC15 - USB pullup. + # Text command protocol Text commands have format of `parameter[number][=setter]`. Where - *parameter* is any possible command, diff --git a/F3:F303/CANbus4BTA/commonfunctions.c b/F3:F303/CANbus4BTA/commonfunctions.c index ca19889..2e912f3 100644 --- a/F3:F303/CANbus4BTA/commonfunctions.c +++ b/F3:F303/CANbus4BTA/commonfunctions.c @@ -43,6 +43,14 @@ static errcodes time_getset(CAN_message *msg){ *(uint32_t*)&msg->data[4] = Tms; return ERR_OK; } +// get/set timestamp +static errcodes timestamp_getset(CAN_message *msg){ + if(ISSETTER(msg->data)){ + TIM2->CNT = *(uint32_t*)&msg->data[4]; + }else FIXDL(msg); + *(uint32_t*)&msg->data[4] = TIM2->CNT; + return ERR_OK; +} // get MCU T static errcodes mcut(CAN_message *msg){ FIXDL(msg); @@ -138,6 +146,11 @@ static errcodes encget(CAN_message *msg){ if(read_encoder(msg->data + 4)) return ERR_OK; return ERR_CANTRUN; } +// reinit encoder +static errcodes encreinit(CAN_message _U_ *msg){ + encoder_setup(); + return ERR_OK; +} // common uint32_t setter/getter static errcodes u32setget(CAN_message *msg){ @@ -204,6 +217,9 @@ static const commonfunction funclist[CMD_AMOUNT] = { [CMD_SPIINIT] = {initspi2, 0, 0, 0}, [CMD_SPISEND] = {sendspi2, 0, 0, 5}, [CMD_ENCGET] = {encget, 0, 0, 0}, + [CMD_EMULPEP] = {flagsetget, 0, 0, 0}, + [CMD_ENCREINIT] = {encreinit, 0, 0, 0}, + [CMD_TIMESTAMP] = {timestamp_getset, 0, 0xffffff, 0}, }; diff --git a/F3:F303/CANbus4BTA/encoder.c b/F3:F303/CANbus4BTA/encoder.c index 3969cc7..9e16465 100644 --- a/F3:F303/CANbus4BTA/encoder.c +++ b/F3:F303/CANbus4BTA/encoder.c @@ -16,15 +16,23 @@ * along with this program. If not, see . */ +#include "can.h" #include "encoder.h" #include "flash.h" +#include "gpio.h" #include "spi.h" #include "usart.h" +#include void encoder_setup(){ - if(FLAG(ENC_IS_SSI)) spi_setup(ENCODER_SPI); - else usart_setup(); + if(FLAG(ENC_IS_SSI)){ + usart_deinit(); + spi_setup(ENCODER_SPI); + }else{ + spi_deinit(ENCODER_SPI); + usart_setup(); + } } // read encoder value into buffer `outbuf` @@ -34,3 +42,22 @@ int read_encoder(uint8_t outbuf[4]){ *((uint32_t*)outbuf) = 0; return spi_writeread(ENCODER_SPI, outbuf, 4); } + +// send encoder data +void CANsendEnc(){ + CAN_message msg = {.data = {0}, .ID = the_conf.encoderID, .length = 8}; + if(!read_encoder(msg.data)) return; + uint32_t ctr = TIM2->CNT; + //msg.data[4] = 0; + msg.data[5] = (ctr >> 16) & 0xff; + msg.data[6] = (ctr >> 8 ) & 0xff; + msg.data[7] = (ctr >> 0 ) & 0xff; + CAN_send(&msg); +} +// send limit-switches data +void CANsendLim(){ + CAN_message msg = {.data = {0}, .ID = the_conf.limitsID, .length = 8}; + msg.data[2] = getESW(0); + msg.data[3] = getESW(1); + CAN_send(&msg); +} diff --git a/F3:F303/CANbus4BTA/encoder.h b/F3:F303/CANbus4BTA/encoder.h index e935349..41addc3 100644 --- a/F3:F303/CANbus4BTA/encoder.h +++ b/F3:F303/CANbus4BTA/encoder.h @@ -22,3 +22,5 @@ void encoder_setup(); int read_encoder(uint8_t outbuf[4]); +void CANsendEnc(); +void CANsendLim(); diff --git a/F3:F303/CANbus4BTA/flash.c b/F3:F303/CANbus4BTA/flash.c index 0fbe9ed..f4610d1 100644 --- a/F3:F303/CANbus4BTA/flash.c +++ b/F3:F303/CANbus4BTA/flash.c @@ -46,7 +46,9 @@ user_conf the_conf = { .adcmul[2] = 1.f, .adcmul[3] = 1.f, .usartspeed = 115200, - .flags = FLAGP(ENC_IS_SSI), + .encoderID = 8, + .limitsID = 0xe, + .flags = FLAGP(ENC_IS_SSI) /*| FLAGP(EMULATE_PEP)*/, }; int currentconfidx = -1; // index of current configuration diff --git a/F3:F303/CANbus4BTA/flash.h b/F3:F303/CANbus4BTA/flash.h index fe0e8a4..44a958b 100644 --- a/F3:F303/CANbus4BTA/flash.h +++ b/F3:F303/CANbus4BTA/flash.h @@ -31,6 +31,8 @@ // bit flags positions // encoder have SSI (1) or RS-422 (0) #define ENC_IS_SSI_BIT 0 +// old PEP behaviour +#define EMULATE_PEP_BIT 1 // bit number #define FLAGBIT(f) (f ## _BIT) @@ -53,6 +55,8 @@ typedef struct __attribute__((packed, aligned(4))){ uint32_t bounce_ms; // debounce wait float adcmul[ADC_TSENS]; // ADC voltage multipliers uint32_t usartspeed; // USART1 speed (baud/s) + uint16_t encoderID; // CANbus encoders' ID (PEP emulation) + uint16_t limitsID; // CANbus limits' ID (PEP emulation) uint32_t flags; // bit flags } user_conf; diff --git a/F3:F303/CANbus4BTA/hardware.c b/F3:F303/CANbus4BTA/hardware.c index 5989c59..b4cd3fe 100644 --- a/F3:F303/CANbus4BTA/hardware.c +++ b/F3:F303/CANbus4BTA/hardware.c @@ -46,7 +46,17 @@ TRUE_INLINE void iwdg_setup(){ } #endif -static inline void gpio_setup(){ +// setup TIM2 as 24-bit 2mks timestamp counter +TRUE_INLINE void tim2_setup(){ + TIM2->CR1 = 0; // turn off timer + RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // enable clocking + TIM2->PSC = 143; // 500kHz + TIM2->ARR = 0xffffff; // 24 bit counter from 0xffffff to 0 + // turn it on, downcounting + TIM2->CR1 = TIM_CR1_CEN | TIM_CR1_DIR; +} + +TRUE_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; SWD - AF0 @PA13/14 @@ -73,6 +83,7 @@ static inline void gpio_setup(){ } void hw_setup(){ + tim2_setup(); gpio_setup(); adc_setup(); USB_setup(); diff --git a/F3:F303/CANbus4BTA/hardware.h b/F3:F303/CANbus4BTA/hardware.h index 9da78f9..26dd084 100644 --- a/F3:F303/CANbus4BTA/hardware.h +++ b/F3:F303/CANbus4BTA/hardware.h @@ -20,6 +20,9 @@ #include +// PEP emulation - period of encoder/esw data send - 70ms +#define ENCODER_PERIOD (69) + // USB pullup #define USBPU_port GPIOC #define USBPU_pin (1<<15) diff --git a/F3:F303/CANbus4BTA/main.c b/F3:F303/CANbus4BTA/main.c index 56dd9bf..4778379 100644 --- a/F3:F303/CANbus4BTA/main.c +++ b/F3:F303/CANbus4BTA/main.c @@ -50,6 +50,7 @@ TRUE_INLINE void showCANmessages(){ int main(void){ char inbuff[MAXSTRLEN+1]; + uint32_t encT = 0; // time of ENC and LIM data sent (PEP emulation) USBPU_OFF(); if(StartHSE()){ SysTick_Config((uint32_t)72000); // 1ms @@ -75,15 +76,6 @@ int main(void){ CAN_reinit(0); } if(cansniffer) showCANmessages(); - /*if(bufovr){ - bufovr = 0; - USB_sendstr("error=uartoverflow\n"); - }*/ - char *txt = NULL; - if(usart_getline(&txt)){ - const char *ans = run_text_cmd(txt); - if(ans) usart_send(ans); - } int l = USB_receivestr(inbuff, MAXSTRLEN); if(l < 0) USB_sendstr("error=usboverflow\n"); else if(l){ @@ -92,13 +84,22 @@ int main(void){ } ESW_process(); static uint8_t oldswitches[2] = {0}; + int send = 0; for(int i = 0; i < 2; ++i){ uint8_t new = getESW(i); if(oldswitches[i] != new){ + send = 1; oldswitches[i] = new; - USB_sendstr("ESW changed @"); printu(Tms); + USB_sendstr("ESW"); USB_putbyte('0' + i); + USB_sendstr(" changed @"); printu(Tms); USB_sendstr(" to "); printuhex(new); newline(); } } + if(FLAG(EMULATE_PEP)){ + if(Tms - encT > ENCODER_PERIOD){ + encT = Tms; + CANsendEnc(); + } else if(send) CANsendLim(); + } } } diff --git a/F3:F303/CANbus4BTA/proto.h b/F3:F303/CANbus4BTA/proto.h index 186e3f7..9f48e09 100644 --- a/F3:F303/CANbus4BTA/proto.h +++ b/F3:F303/CANbus4BTA/proto.h @@ -69,6 +69,9 @@ typedef enum{ 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_AMOUNT // amount of CAN commands } can_cmd; diff --git a/F3:F303/CANbus4BTA/spi.c b/F3:F303/CANbus4BTA/spi.c index 2026617..7867e5c 100644 --- a/F3:F303/CANbus4BTA/spi.c +++ b/F3:F303/CANbus4BTA/spi.c @@ -26,6 +26,9 @@ //#define SPIDR *((volatile uint8_t*)&SPI2->DR) +#define CHKIDX(idx) do{if(idx == 0 || idx > AMOUNT_OF_SPI) return;}while(0) +#define CHKIDXR(idx) do{if(idx == 0 || idx > AMOUNT_OF_SPI) return 0;}while(0) + spiStatus spi_status[AMOUNT_OF_SPI+1] = {0, SPI_NOTREADY, SPI_NOTREADY}; static volatile SPI_TypeDef* const SPIs[AMOUNT_OF_SPI+1] = {NULL, SPI1, SPI2}; #define WAITX(x) do{volatile uint32_t wctr = 0; while((x) && (++wctr < 360000)) IWDG->KR = IWDG_REFRESH; if(wctr==360000){ DBG("timeout"); return 0;}}while(0) @@ -38,7 +41,7 @@ static volatile SPI_TypeDef* const SPIs[AMOUNT_OF_SPI+1] = {NULL, SPI1, SPI2}; // Channel 4 - SPI2 Rx // Channel 5 - SPI2 Tx void spi_setup(uint8_t idx){ - if(idx > AMOUNT_OF_SPI) return; + CHKIDX(idx); volatile SPI_TypeDef *SPI = SPIs[idx]; SPI->CR1 = 0; // clear EN SPI->CR2 = 0; @@ -59,9 +62,9 @@ void spi_setup(uint8_t idx){ RCC->APB1RSTR = RCC_APB1RSTR_SPI2RST; // reset SPI RCC->APB1RSTR = 0; // clear reset RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; - RCC->AHBENR |= RCC_AHBENR_DMA1EN; SPI->CR2 = SPI_CR2_SSOE; // hardware NSS management // setup SPI2 DMA + //RCC->AHBENR |= RCC_AHBENR_DMA1EN; //SPI->CR2 |= SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN; // Tx /*DMA1_Channel5->CPAR = (uint32_t)&(SPI2->DR); // hardware @@ -82,8 +85,25 @@ void spi_setup(uint8_t idx){ DBG("SPI works"); } +// turn off given SPI channel and release GPIO +void spi_deinit(uint8_t idx){ + CHKIDX(idx); + volatile SPI_TypeDef *SPI = SPIs[idx]; + SPI->CR1 = 0; + SPI->CR2 = 0; + if(idx == 1){ + RCC->APB2ENR &= ~RCC_APB2ENR_SPI1EN; + GPIOB->AFR[0] = GPIOB->AFR[0] & ~(GPIO_AFRL_AFRL3 | GPIO_AFRL_AFRL4); + GPIOB->MODER = GPIOB->MODER & ~(GPIO_MODER_MODER3 | GPIO_MODER_MODER4); + }else if(idx == 2){ + RCC->APB1ENR &= ~RCC_APB1ENR_SPI2EN; + GPIOB->AFR[1] = GPIOB->AFR[1] & ~(GPIO_AFRH_AFRH4 | GPIO_AFRH_AFRH5 | GPIO_AFRH_AFRH6 | GPIO_AFRH_AFRH7); + GPIOB->MODER = GPIOB->MODER & ~(GPIO_MODER_MODER12 | GPIO_MODER_MODER13 | GPIO_MODER_MODER14 | GPIO_MODER_MODER15); + } +} + int spi_waitbsy(uint8_t idx){ - if(idx > AMOUNT_OF_SPI) return 0; + CHKIDXR(idx); WAITX(SPIs[idx]->SR & SPI_SR_BSY); return 1; } @@ -95,7 +115,7 @@ int spi_waitbsy(uint8_t idx){ * @return 0 if failed */ int spi_writeread(uint8_t idx, uint8_t *data, uint32_t n){ - if(idx > AMOUNT_OF_SPI) return 0; + CHKIDXR(idx); if(spi_status[idx] != SPI_READY || !data || !n){ DBG("not ready"); return 0; @@ -146,7 +166,7 @@ int spi_writeread(uint8_t idx, uint8_t *data, uint32_t n){ */ /* int spi_read(uint8_t idx, uint8_t *data, uint32_t n){ - if(idx > AMOUNT_OF_SPI) return 0; + CHKIDXR(idx); if(spi_status[idx] != SPI_READY){ DBG("not ready"); return 0; diff --git a/F3:F303/CANbus4BTA/spi.h b/F3:F303/CANbus4BTA/spi.h index e617fa6..9f3a870 100644 --- a/F3:F303/CANbus4BTA/spi.h +++ b/F3:F303/CANbus4BTA/spi.h @@ -29,6 +29,7 @@ typedef enum{ extern spiStatus spi_status[AMOUNT_OF_SPI+1]; +void spi_deinit(uint8_t idx); void spi_setup(uint8_t idx); int spi_waitbsy(uint8_t idx); int spi_writeread(uint8_t idx, uint8_t *data, uint32_t n); diff --git a/F3:F303/CANbus4BTA/textfunctions.c b/F3:F303/CANbus4BTA/textfunctions.c index bf6638c..fc12ca5 100644 --- a/F3:F303/CANbus4BTA/textfunctions.c +++ b/F3:F303/CANbus4BTA/textfunctions.c @@ -58,16 +58,23 @@ static const funcdescr funclist[] = { {"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"}, + {"encget", CMD_ENCGET, "read encoder data"}, + {"encreinit", CMD_ENCREINIT, "reinit encoder"}, + {"encssi", CMD_ENCISSSI, "encoder is SSI (1) or RS-422 (0)"}, {"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)"}, + {"pepemul", CMD_EMULPEP, "emulate (1) / not (0) PEP"}, {"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"}, {"spiinit", CMD_SPIINIT, "init SPI2"}, - {"time", CMD_TIME, "get/set time (ms)"}, + {"spisend", CMD_SPISEND, "send 4 bytes over SPI2"}, + {"time", CMD_TIME, "get/set time (1ms, 32bit)"}, + {"timestamp", CMD_TIMESTAMP, "get/set timestamp (2mks, 24bit)"}, + {"usartspeed", CMD_USARTSPEED, "get/set USART1 speed"}, {"wdtest", -TCMD_WDTEST, "test watchdog"}, {NULL, 0, NULL} // last record }; diff --git a/F3:F303/CANbus4BTA/usart.c b/F3:F303/CANbus4BTA/usart.c index 40b84d0..ab3ed58 100644 --- a/F3:F303/CANbus4BTA/usart.c +++ b/F3:F303/CANbus4BTA/usart.c @@ -24,7 +24,7 @@ static volatile int idatalen = 0; // received data line length (including '\n') -volatile int linerdy = 0, // received data ready +static volatile int linerdy = 0, // received data ready dlen = 0, // length of data (including '\n') in current buffer bufovr = 0; // input buffer overfull @@ -65,9 +65,17 @@ void usart_send(const char *str){ usart_sendn(str, L); } +// turn off USART1 and deinit GPIO +void usart_deinit(){ + USART1->ICR = 0xffffffff; + USART1->CR1 = 0; + RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN; + GPIOA->AFR[1] = GPIOA->AFR[1] & ~(GPIO_AFRH_AFRH1 | GPIO_AFRH_AFRH2); + GPIOA->MODER = GPIOA->MODER & ~(GPIO_MODER_MODER9 | GPIO_MODER_MODER10); +} + // USART1: PA10(Rx, pullup), PA9(Tx); USART1 = AF7 @PA9/10; void usart_setup(){ - // clock GPIOA->MODER = (GPIOA->MODER & ~(GPIO_MODER_MODER9 | GPIO_MODER_MODER10)) | MODER_AF(9) | MODER_AF(10); GPIOA->AFR[1] = (GPIOA->AFR[1] & ~(GPIO_AFRH_AFRH1 | GPIO_AFRH_AFRH2)) | diff --git a/F3:F303/CANbus4BTA/usart.h b/F3:F303/CANbus4BTA/usart.h index a0198e0..e75f1ce 100644 --- a/F3:F303/CANbus4BTA/usart.h +++ b/F3:F303/CANbus4BTA/usart.h @@ -23,9 +23,8 @@ // input buffers size #define UARTBUFSZ (80) -extern volatile int linerdy, bufovr; - void usart_setup(); +void usart_deinit(); int usart_getline(char **line); void usart_send(const char *str); void usart_sendn(const char *str, int L); diff --git a/F3:F303/CANbus4BTA/version.inc b/F3:F303/CANbus4BTA/version.inc index cb5140d..afd5a14 100644 --- a/F3:F303/CANbus4BTA/version.inc +++ b/F3:F303/CANbus4BTA/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "80" -#define BUILD_DATE "2024-03-07" +#define BUILD_NUMBER "84" +#define BUILD_DATE "2024-03-08"