diff --git a/F3:F303/CANbus4BTA/BTA_CAN.bin b/F3:F303/CANbus4BTA/BTA_CAN.bin
index 53faf23..ca20479 100755
Binary files a/F3:F303/CANbus4BTA/BTA_CAN.bin and b/F3:F303/CANbus4BTA/BTA_CAN.bin differ
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"