mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 18:55:13 +03:00
PEP emulation (didn't test yet)
This commit is contained in:
parent
8ea835d80f
commit
bc82142e87
Binary file not shown.
@ -122,6 +122,59 @@ Channel1 - ADC1.
|
|||||||
|
|
||||||
## DMA2
|
## 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 command protocol
|
||||||
Text commands have format of `parameter[number][=setter]`. Where
|
Text commands have format of `parameter[number][=setter]`. Where
|
||||||
- *parameter* is any possible command,
|
- *parameter* is any possible command,
|
||||||
|
|||||||
@ -43,6 +43,14 @@ static errcodes time_getset(CAN_message *msg){
|
|||||||
*(uint32_t*)&msg->data[4] = Tms;
|
*(uint32_t*)&msg->data[4] = Tms;
|
||||||
return ERR_OK;
|
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
|
// get MCU T
|
||||||
static errcodes mcut(CAN_message *msg){
|
static errcodes mcut(CAN_message *msg){
|
||||||
FIXDL(msg);
|
FIXDL(msg);
|
||||||
@ -138,6 +146,11 @@ static errcodes encget(CAN_message *msg){
|
|||||||
if(read_encoder(msg->data + 4)) return ERR_OK;
|
if(read_encoder(msg->data + 4)) return ERR_OK;
|
||||||
return ERR_CANTRUN;
|
return ERR_CANTRUN;
|
||||||
}
|
}
|
||||||
|
// reinit encoder
|
||||||
|
static errcodes encreinit(CAN_message _U_ *msg){
|
||||||
|
encoder_setup();
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// common uint32_t setter/getter
|
// common uint32_t setter/getter
|
||||||
static errcodes u32setget(CAN_message *msg){
|
static errcodes u32setget(CAN_message *msg){
|
||||||
@ -204,6 +217,9 @@ static const commonfunction funclist[CMD_AMOUNT] = {
|
|||||||
[CMD_SPIINIT] = {initspi2, 0, 0, 0},
|
[CMD_SPIINIT] = {initspi2, 0, 0, 0},
|
||||||
[CMD_SPISEND] = {sendspi2, 0, 0, 5},
|
[CMD_SPISEND] = {sendspi2, 0, 0, 5},
|
||||||
[CMD_ENCGET] = {encget, 0, 0, 0},
|
[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},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -16,15 +16,23 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "can.h"
|
||||||
#include "encoder.h"
|
#include "encoder.h"
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
|
#include "gpio.h"
|
||||||
#include "spi.h"
|
#include "spi.h"
|
||||||
#include "usart.h"
|
#include "usart.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
void encoder_setup(){
|
void encoder_setup(){
|
||||||
if(FLAG(ENC_IS_SSI)) spi_setup(ENCODER_SPI);
|
if(FLAG(ENC_IS_SSI)){
|
||||||
else usart_setup();
|
usart_deinit();
|
||||||
|
spi_setup(ENCODER_SPI);
|
||||||
|
}else{
|
||||||
|
spi_deinit(ENCODER_SPI);
|
||||||
|
usart_setup();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// read encoder value into buffer `outbuf`
|
// read encoder value into buffer `outbuf`
|
||||||
@ -34,3 +42,22 @@ int read_encoder(uint8_t outbuf[4]){
|
|||||||
*((uint32_t*)outbuf) = 0;
|
*((uint32_t*)outbuf) = 0;
|
||||||
return spi_writeread(ENCODER_SPI, outbuf, 4);
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@ -22,3 +22,5 @@
|
|||||||
|
|
||||||
void encoder_setup();
|
void encoder_setup();
|
||||||
int read_encoder(uint8_t outbuf[4]);
|
int read_encoder(uint8_t outbuf[4]);
|
||||||
|
void CANsendEnc();
|
||||||
|
void CANsendLim();
|
||||||
|
|||||||
@ -46,7 +46,9 @@ user_conf the_conf = {
|
|||||||
.adcmul[2] = 1.f,
|
.adcmul[2] = 1.f,
|
||||||
.adcmul[3] = 1.f,
|
.adcmul[3] = 1.f,
|
||||||
.usartspeed = 115200,
|
.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
|
int currentconfidx = -1; // index of current configuration
|
||||||
|
|||||||
@ -31,6 +31,8 @@
|
|||||||
// bit flags positions
|
// bit flags positions
|
||||||
// encoder have SSI (1) or RS-422 (0)
|
// encoder have SSI (1) or RS-422 (0)
|
||||||
#define ENC_IS_SSI_BIT 0
|
#define ENC_IS_SSI_BIT 0
|
||||||
|
// old PEP behaviour
|
||||||
|
#define EMULATE_PEP_BIT 1
|
||||||
|
|
||||||
// bit number
|
// bit number
|
||||||
#define FLAGBIT(f) (f ## _BIT)
|
#define FLAGBIT(f) (f ## _BIT)
|
||||||
@ -53,6 +55,8 @@ typedef struct __attribute__((packed, aligned(4))){
|
|||||||
uint32_t bounce_ms; // debounce wait
|
uint32_t bounce_ms; // debounce wait
|
||||||
float adcmul[ADC_TSENS]; // ADC voltage multipliers
|
float adcmul[ADC_TSENS]; // ADC voltage multipliers
|
||||||
uint32_t usartspeed; // USART1 speed (baud/s)
|
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
|
uint32_t flags; // bit flags
|
||||||
} user_conf;
|
} user_conf;
|
||||||
|
|
||||||
|
|||||||
@ -46,7 +46,17 @@ TRUE_INLINE void iwdg_setup(){
|
|||||||
}
|
}
|
||||||
#endif
|
#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);
|
RELAY_OFF(); MUL_OFF(0); MUL_OFF(1);
|
||||||
RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOCEN;
|
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
|
// 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(){
|
void hw_setup(){
|
||||||
|
tim2_setup();
|
||||||
gpio_setup();
|
gpio_setup();
|
||||||
adc_setup();
|
adc_setup();
|
||||||
USB_setup();
|
USB_setup();
|
||||||
|
|||||||
@ -20,6 +20,9 @@
|
|||||||
|
|
||||||
#include <stm32f3.h>
|
#include <stm32f3.h>
|
||||||
|
|
||||||
|
// PEP emulation - period of encoder/esw data send - 70ms
|
||||||
|
#define ENCODER_PERIOD (69)
|
||||||
|
|
||||||
// USB pullup
|
// USB pullup
|
||||||
#define USBPU_port GPIOC
|
#define USBPU_port GPIOC
|
||||||
#define USBPU_pin (1<<15)
|
#define USBPU_pin (1<<15)
|
||||||
|
|||||||
@ -50,6 +50,7 @@ TRUE_INLINE void showCANmessages(){
|
|||||||
|
|
||||||
int main(void){
|
int main(void){
|
||||||
char inbuff[MAXSTRLEN+1];
|
char inbuff[MAXSTRLEN+1];
|
||||||
|
uint32_t encT = 0; // time of ENC and LIM data sent (PEP emulation)
|
||||||
USBPU_OFF();
|
USBPU_OFF();
|
||||||
if(StartHSE()){
|
if(StartHSE()){
|
||||||
SysTick_Config((uint32_t)72000); // 1ms
|
SysTick_Config((uint32_t)72000); // 1ms
|
||||||
@ -75,15 +76,6 @@ int main(void){
|
|||||||
CAN_reinit(0);
|
CAN_reinit(0);
|
||||||
}
|
}
|
||||||
if(cansniffer) showCANmessages();
|
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);
|
int l = USB_receivestr(inbuff, MAXSTRLEN);
|
||||||
if(l < 0) USB_sendstr("error=usboverflow\n");
|
if(l < 0) USB_sendstr("error=usboverflow\n");
|
||||||
else if(l){
|
else if(l){
|
||||||
@ -92,13 +84,22 @@ int main(void){
|
|||||||
}
|
}
|
||||||
ESW_process();
|
ESW_process();
|
||||||
static uint8_t oldswitches[2] = {0};
|
static uint8_t oldswitches[2] = {0};
|
||||||
|
int send = 0;
|
||||||
for(int i = 0; i < 2; ++i){
|
for(int i = 0; i < 2; ++i){
|
||||||
uint8_t new = getESW(i);
|
uint8_t new = getESW(i);
|
||||||
if(oldswitches[i] != new){
|
if(oldswitches[i] != new){
|
||||||
|
send = 1;
|
||||||
oldswitches[i] = new;
|
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();
|
USB_sendstr(" to "); printuhex(new); newline();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(FLAG(EMULATE_PEP)){
|
||||||
|
if(Tms - encT > ENCODER_PERIOD){
|
||||||
|
encT = Tms;
|
||||||
|
CANsendEnc();
|
||||||
|
} else if(send) CANsendLim();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -69,6 +69,9 @@ typedef enum{
|
|||||||
CMD_SPIINIT, // 16 - init SPI2
|
CMD_SPIINIT, // 16 - init SPI2
|
||||||
CMD_SPISEND, // 17 - send 1..4 bytes over SPI
|
CMD_SPISEND, // 17 - send 1..4 bytes over SPI
|
||||||
CMD_ENCGET, // 18 - get encoder value
|
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
|
CMD_AMOUNT // amount of CAN commands
|
||||||
} can_cmd;
|
} can_cmd;
|
||||||
|
|
||||||
|
|||||||
@ -26,6 +26,9 @@
|
|||||||
|
|
||||||
//#define SPIDR *((volatile uint8_t*)&SPI2->DR)
|
//#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};
|
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};
|
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)
|
#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 4 - SPI2 Rx
|
||||||
// Channel 5 - SPI2 Tx
|
// Channel 5 - SPI2 Tx
|
||||||
void spi_setup(uint8_t idx){
|
void spi_setup(uint8_t idx){
|
||||||
if(idx > AMOUNT_OF_SPI) return;
|
CHKIDX(idx);
|
||||||
volatile SPI_TypeDef *SPI = SPIs[idx];
|
volatile SPI_TypeDef *SPI = SPIs[idx];
|
||||||
SPI->CR1 = 0; // clear EN
|
SPI->CR1 = 0; // clear EN
|
||||||
SPI->CR2 = 0;
|
SPI->CR2 = 0;
|
||||||
@ -59,9 +62,9 @@ void spi_setup(uint8_t idx){
|
|||||||
RCC->APB1RSTR = RCC_APB1RSTR_SPI2RST; // reset SPI
|
RCC->APB1RSTR = RCC_APB1RSTR_SPI2RST; // reset SPI
|
||||||
RCC->APB1RSTR = 0; // clear reset
|
RCC->APB1RSTR = 0; // clear reset
|
||||||
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;
|
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;
|
||||||
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
|
|
||||||
SPI->CR2 = SPI_CR2_SSOE; // hardware NSS management
|
SPI->CR2 = SPI_CR2_SSOE; // hardware NSS management
|
||||||
// setup SPI2 DMA
|
// setup SPI2 DMA
|
||||||
|
//RCC->AHBENR |= RCC_AHBENR_DMA1EN;
|
||||||
//SPI->CR2 |= SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN;
|
//SPI->CR2 |= SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN;
|
||||||
// Tx
|
// Tx
|
||||||
/*DMA1_Channel5->CPAR = (uint32_t)&(SPI2->DR); // hardware
|
/*DMA1_Channel5->CPAR = (uint32_t)&(SPI2->DR); // hardware
|
||||||
@ -82,8 +85,25 @@ void spi_setup(uint8_t idx){
|
|||||||
DBG("SPI works");
|
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){
|
int spi_waitbsy(uint8_t idx){
|
||||||
if(idx > AMOUNT_OF_SPI) return 0;
|
CHKIDXR(idx);
|
||||||
WAITX(SPIs[idx]->SR & SPI_SR_BSY);
|
WAITX(SPIs[idx]->SR & SPI_SR_BSY);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -95,7 +115,7 @@ int spi_waitbsy(uint8_t idx){
|
|||||||
* @return 0 if failed
|
* @return 0 if failed
|
||||||
*/
|
*/
|
||||||
int spi_writeread(uint8_t idx, uint8_t *data, uint32_t n){
|
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){
|
if(spi_status[idx] != SPI_READY || !data || !n){
|
||||||
DBG("not ready");
|
DBG("not ready");
|
||||||
return 0;
|
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){
|
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){
|
if(spi_status[idx] != SPI_READY){
|
||||||
DBG("not ready");
|
DBG("not ready");
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -29,6 +29,7 @@ typedef enum{
|
|||||||
|
|
||||||
extern spiStatus spi_status[AMOUNT_OF_SPI+1];
|
extern spiStatus spi_status[AMOUNT_OF_SPI+1];
|
||||||
|
|
||||||
|
void spi_deinit(uint8_t idx);
|
||||||
void spi_setup(uint8_t idx);
|
void spi_setup(uint8_t idx);
|
||||||
int spi_waitbsy(uint8_t idx);
|
int spi_waitbsy(uint8_t idx);
|
||||||
int spi_writeread(uint8_t idx, uint8_t *data, uint32_t n);
|
int spi_writeread(uint8_t idx, uint8_t *data, uint32_t n);
|
||||||
|
|||||||
@ -58,16 +58,23 @@ static const funcdescr funclist[] = {
|
|||||||
{"cansnif", -TCMD_CANSNIF, "get/change sniffer state (0 - normal, 1 - sniffer)"},
|
{"cansnif", -TCMD_CANSNIF, "get/change sniffer state (0 - normal, 1 - sniffer)"},
|
||||||
{"canspeed", CMD_CANSPEED, "get/set CAN speed (bps)"},
|
{"canspeed", CMD_CANSPEED, "get/set CAN speed (bps)"},
|
||||||
{"dumpconf", -TCMD_DUMPCONF, "dump current configuration"},
|
{"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"},
|
{"esw", CMD_GETESW, "anti-bounce read ESW of channel 0 or 1"},
|
||||||
{"eswblk", CMD_GETESW_BLK, "blocking 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"},
|
{"eraseflash", CMD_ERASESTOR, "erase all flash storage"},
|
||||||
{"mcutemp", CMD_MCUTEMP, "get MCU temperature (*10degrC)"},
|
{"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)"},
|
{"relay", CMD_RELAY, "get/set relay state (0 - off, 1 - on)"},
|
||||||
{"reset", CMD_RESET, "reset MCU"},
|
{"reset", CMD_RESET, "reset MCU"},
|
||||||
{"s", -TCMD_CANSEND, "send CAN message: ID 0..8 data bytes"},
|
{"s", -TCMD_CANSEND, "send CAN message: ID 0..8 data bytes"},
|
||||||
{"saveconf", CMD_SAVECONF, "save configuration"},
|
{"saveconf", CMD_SAVECONF, "save configuration"},
|
||||||
{"spiinit", CMD_SPIINIT, "init SPI2"},
|
{"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"},
|
{"wdtest", -TCMD_WDTEST, "test watchdog"},
|
||||||
{NULL, 0, NULL} // last record
|
{NULL, 0, NULL} // last record
|
||||||
};
|
};
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
static volatile int idatalen = 0; // received data line length (including '\n')
|
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
|
dlen = 0, // length of data (including '\n') in current buffer
|
||||||
bufovr = 0; // input buffer overfull
|
bufovr = 0; // input buffer overfull
|
||||||
|
|
||||||
@ -65,9 +65,17 @@ void usart_send(const char *str){
|
|||||||
usart_sendn(str, L);
|
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;
|
// USART1: PA10(Rx, pullup), PA9(Tx); USART1 = AF7 @PA9/10;
|
||||||
void usart_setup(){
|
void usart_setup(){
|
||||||
// clock
|
|
||||||
GPIOA->MODER = (GPIOA->MODER & ~(GPIO_MODER_MODER9 | GPIO_MODER_MODER10)) |
|
GPIOA->MODER = (GPIOA->MODER & ~(GPIO_MODER_MODER9 | GPIO_MODER_MODER10)) |
|
||||||
MODER_AF(9) | MODER_AF(10);
|
MODER_AF(9) | MODER_AF(10);
|
||||||
GPIOA->AFR[1] = (GPIOA->AFR[1] & ~(GPIO_AFRH_AFRH1 | GPIO_AFRH_AFRH2)) |
|
GPIOA->AFR[1] = (GPIOA->AFR[1] & ~(GPIO_AFRH_AFRH1 | GPIO_AFRH_AFRH2)) |
|
||||||
|
|||||||
@ -23,9 +23,8 @@
|
|||||||
// input buffers size
|
// input buffers size
|
||||||
#define UARTBUFSZ (80)
|
#define UARTBUFSZ (80)
|
||||||
|
|
||||||
extern volatile int linerdy, bufovr;
|
|
||||||
|
|
||||||
void usart_setup();
|
void usart_setup();
|
||||||
|
void usart_deinit();
|
||||||
int usart_getline(char **line);
|
int usart_getline(char **line);
|
||||||
void usart_send(const char *str);
|
void usart_send(const char *str);
|
||||||
void usart_sendn(const char *str, int L);
|
void usart_sendn(const char *str, int L);
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
#define BUILD_NUMBER "80"
|
#define BUILD_NUMBER "84"
|
||||||
#define BUILD_DATE "2024-03-07"
|
#define BUILD_DATE "2024-03-08"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user