mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 18:55:13 +03:00
Add flood & pause commands
This commit is contained in:
parent
360de69497
commit
e51a45040b
@ -8,7 +8,7 @@ MCU = F042x6
|
|||||||
# hardware definitions
|
# hardware definitions
|
||||||
DEFS += -DUSARTNUM=1
|
DEFS += -DUSARTNUM=1
|
||||||
#DEFS += -DCHECK_TMOUT
|
#DEFS += -DCHECK_TMOUT
|
||||||
DEFS += -DEBUG
|
#DEFS += -DEBUG
|
||||||
# change this linking script depending on particular MCU model,
|
# change this linking script depending on particular MCU model,
|
||||||
# for example, if you have STM32F103VBT6, you should write:
|
# for example, if you have STM32F103VBT6, you should write:
|
||||||
LDSCRIPT = stm32f042k.ld
|
LDSCRIPT = stm32f042k.ld
|
||||||
|
|||||||
@ -41,6 +41,9 @@ static CAN_status can_status = CAN_STOP;
|
|||||||
|
|
||||||
static void can_process_fifo(uint8_t fifo_num);
|
static void can_process_fifo(uint8_t fifo_num);
|
||||||
|
|
||||||
|
static CAN_message loc_flood_msg;
|
||||||
|
static CAN_message *flood_msg = NULL; // == loc_flood_msg - to flood
|
||||||
|
|
||||||
CAN_status CAN_get_status(){
|
CAN_status CAN_get_status(){
|
||||||
CAN_status st = can_status;
|
CAN_status st = can_status;
|
||||||
// give overrun message only once
|
// give overrun message only once
|
||||||
@ -205,9 +208,9 @@ void can_proc(){
|
|||||||
if(CAN->RF1R & CAN_RF1R_FMP1){
|
if(CAN->RF1R & CAN_RF1R_FMP1){
|
||||||
can_process_fifo(1);
|
can_process_fifo(1);
|
||||||
}
|
}
|
||||||
|
IWDG->KR = IWDG_REFRESH;
|
||||||
if(CAN->ESR & (CAN_ESR_BOFF | CAN_ESR_EPVF | CAN_ESR_EWGF)){ // much errors - restart CAN BUS
|
if(CAN->ESR & (CAN_ESR_BOFF | CAN_ESR_EPVF | CAN_ESR_EWGF)){ // much errors - restart CAN BUS
|
||||||
switchbuff(0);
|
SEND("\nToo much errors, restarting CAN!\n");
|
||||||
SEND("\nToo much errors, restarting!\n");
|
|
||||||
SEND("Receive error counter: ");
|
SEND("Receive error counter: ");
|
||||||
printu((CAN->ESR & CAN_ESR_REC)>>24);
|
printu((CAN->ESR & CAN_ESR_REC)>>24);
|
||||||
SEND("\nTransmit error counter: ");
|
SEND("\nTransmit error counter: ");
|
||||||
@ -236,6 +239,11 @@ void can_proc(){
|
|||||||
RCC->APB1RSTR &= ~RCC_APB1RSTR_CANRST;
|
RCC->APB1RSTR &= ~RCC_APB1RSTR_CANRST;
|
||||||
CAN_setup(0);
|
CAN_setup(0);
|
||||||
}
|
}
|
||||||
|
static uint32_t lastFloodTime = 0;
|
||||||
|
if(flood_msg && (Tms - lastFloodTime) > (FLOOD_PERIOD_MS-1)){ // flood every ~5ms
|
||||||
|
lastFloodTime = Tms;
|
||||||
|
can_send(flood_msg->data, flood_msg->length, flood_msg->ID);
|
||||||
|
}
|
||||||
#if 0
|
#if 0
|
||||||
static uint32_t esr, msr, tsr;
|
static uint32_t esr, msr, tsr;
|
||||||
uint32_t msr_now = CAN->MSR & 0xf;
|
uint32_t msr_now = CAN->MSR & 0xf;
|
||||||
@ -333,6 +341,14 @@ void can_send_broadcast(){
|
|||||||
MSG("Broadcast message sent\n");
|
MSG("Broadcast message sent\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_flood(CAN_message *msg){
|
||||||
|
if(!msg) flood_msg = NULL;
|
||||||
|
else{
|
||||||
|
memcpy(&loc_flood_msg, msg, sizeof(CAN_message));
|
||||||
|
flood_msg = &loc_flood_msg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void can_process_fifo(uint8_t fifo_num){
|
static void can_process_fifo(uint8_t fifo_num){
|
||||||
if(fifo_num > 1) return;
|
if(fifo_num > 1) return;
|
||||||
LED_on(LED1); // Turn on LED1 - message received
|
LED_on(LED1); // Turn on LED1 - message received
|
||||||
@ -354,8 +370,8 @@ static void can_process_fifo(uint8_t fifo_num){
|
|||||||
uint8_t len = box->RDTR & 0x7;
|
uint8_t len = box->RDTR & 0x7;
|
||||||
msg.length = len;
|
msg.length = len;
|
||||||
msg.ID = box->RIR >> 21;
|
msg.ID = box->RIR >> 21;
|
||||||
msg.filterNo = (box->RDTR >> 8) & 0xff;
|
//msg.filterNo = (box->RDTR >> 8) & 0xff;
|
||||||
msg.fifoNum = fifo_num;
|
//msg.fifoNum = fifo_num;
|
||||||
if(len){ // message can be without data
|
if(len){ // message can be without data
|
||||||
uint32_t hb = box->RDHR, lb = box->RDLR;
|
uint32_t hb = box->RDHR, lb = box->RDLR;
|
||||||
switch(len){
|
switch(len){
|
||||||
|
|||||||
@ -28,6 +28,8 @@
|
|||||||
|
|
||||||
// amount of filter banks in STM32F0
|
// amount of filter banks in STM32F0
|
||||||
#define STM32F0FBANKNO 28
|
#define STM32F0FBANKNO 28
|
||||||
|
// flood period in milliseconds
|
||||||
|
#define FLOOD_PERIOD_MS 5
|
||||||
|
|
||||||
// simple 1-byte commands
|
// simple 1-byte commands
|
||||||
#define CMD_TOGGLE (0xDA)
|
#define CMD_TOGGLE (0xDA)
|
||||||
@ -48,8 +50,8 @@
|
|||||||
typedef struct{
|
typedef struct{
|
||||||
uint8_t data[8]; // up to 8 bytes of data
|
uint8_t data[8]; // up to 8 bytes of data
|
||||||
uint8_t length; // data length
|
uint8_t length; // data length
|
||||||
uint8_t filterNo; // filter number
|
//uint8_t filterNo; // filter number
|
||||||
uint8_t fifoNum; // message FIFO number
|
//uint8_t fifoNum; // message FIFO number
|
||||||
uint16_t ID; // ID of receiver
|
uint16_t ID; // ID of receiver
|
||||||
} CAN_message;
|
} CAN_message;
|
||||||
|
|
||||||
@ -76,4 +78,6 @@ void can_proc();
|
|||||||
|
|
||||||
CAN_message *CAN_messagebuf_pop();
|
CAN_message *CAN_messagebuf_pop();
|
||||||
|
|
||||||
|
void set_flood(CAN_message *msg);
|
||||||
|
|
||||||
#endif // __CAN_H__
|
#endif // __CAN_H__
|
||||||
|
|||||||
@ -105,14 +105,15 @@ int main(void){
|
|||||||
switchbuff(0);
|
switchbuff(0);
|
||||||
SEND("Greetings! My address is ");
|
SEND("Greetings! My address is ");
|
||||||
printuhex(getCANID());
|
printuhex(getCANID());
|
||||||
NL();
|
newline();
|
||||||
|
|
||||||
if(RCC->CSR & RCC_CSR_IWDGRSTF){ // watchdog reset occured
|
if(RCC->CSR & RCC_CSR_IWDGRSTF){ // watchdog reset occured
|
||||||
SEND("WDGRESET=1\n"); NL();
|
SEND("WDGRESET=1\n");
|
||||||
}
|
}
|
||||||
if(RCC->CSR & RCC_CSR_SFTRSTF){ // software reset occured
|
if(RCC->CSR & RCC_CSR_SFTRSTF){ // software reset occured
|
||||||
SEND("SOFTRESET=1\n"); NL();
|
SEND("SOFTRESET=1\n");
|
||||||
}
|
}
|
||||||
|
sendbuf();
|
||||||
RCC->CSR |= RCC_CSR_RMVF; // remove reset flags
|
RCC->CSR |= RCC_CSR_RMVF; // remove reset flags
|
||||||
iwdg_setup();
|
iwdg_setup();
|
||||||
USB_setup();
|
USB_setup();
|
||||||
@ -127,26 +128,27 @@ int main(void){
|
|||||||
can_proc();
|
can_proc();
|
||||||
usb_proc();
|
usb_proc();
|
||||||
if(CAN_get_status() == CAN_FIFO_OVERRUN){
|
if(CAN_get_status() == CAN_FIFO_OVERRUN){
|
||||||
switchbuff(3);
|
register uint8_t o = switchbuff(3);
|
||||||
SEND("CAN bus fifo overrun occured!\n");
|
SEND("CAN bus fifo overrun occured!\n");
|
||||||
newline(); sendbuf();
|
sendbuf(); switchbuff(o);
|
||||||
}
|
}
|
||||||
can_mesg = CAN_messagebuf_pop();
|
can_mesg = CAN_messagebuf_pop();
|
||||||
if(can_mesg && isgood(can_mesg->ID)){ // new data in buff
|
if(ShowMsgs && can_mesg && isgood(can_mesg->ID)){ // new data in buff
|
||||||
|
IWDG->KR = IWDG_REFRESH;
|
||||||
len = can_mesg->length;
|
len = can_mesg->length;
|
||||||
switchbuff(3);
|
printu(Tms);
|
||||||
SEND("got message, ID=");
|
SEND(" #");
|
||||||
printuhex(can_mesg->ID);
|
printuhex(can_mesg->ID);
|
||||||
SEND(", filter #");
|
/*SEND(", filter #");
|
||||||
printu(can_mesg->filterNo);
|
printu(can_mesg->filterNo);
|
||||||
SEND(", FIFO #");
|
SEND(", FIFO #");
|
||||||
printu(can_mesg->fifoNum);
|
printu(can_mesg->fifoNum);*/
|
||||||
SEND(", len=");
|
/*SEND(", len=");
|
||||||
printu(len);
|
printu(len);
|
||||||
SEND(", data: ");
|
SEND(", data: ");*/
|
||||||
for(ctr = 0; ctr < len; ++ctr){
|
for(ctr = 0; ctr < len; ++ctr){
|
||||||
printuhex(can_mesg->data[ctr]);
|
|
||||||
SEND(" ");
|
SEND(" ");
|
||||||
|
printuhex(can_mesg->data[ctr]);
|
||||||
}
|
}
|
||||||
newline(); sendbuf();
|
newline(); sendbuf();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
extern volatile uint8_t canerror;
|
extern volatile uint8_t canerror;
|
||||||
|
|
||||||
|
uint8_t ShowMsgs = 07;
|
||||||
uint16_t Ignore_IDs[IGN_SIZE];
|
uint16_t Ignore_IDs[IGN_SIZE];
|
||||||
uint8_t IgnSz = 0;
|
uint8_t IgnSz = 0;
|
||||||
static char buff[UARTBUFSZ+1], *bptr = buff;
|
static char buff[UARTBUFSZ+1], *bptr = buff;
|
||||||
@ -49,25 +50,13 @@ void sendbuf(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 1 - USB, 0 - USART, other number - both
|
// 1 - USB, 0 - USART, other number - both
|
||||||
void switchbuff(uint8_t isUSB){
|
// @return old buff state
|
||||||
|
uint8_t switchbuff(uint8_t isUSB){
|
||||||
|
uint8_t r = USBcmd;
|
||||||
USBcmd = isUSB;
|
USBcmd = isUSB;
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
void memcpy(void *dest, const void *src, int len){
|
|
||||||
while(len > 4){
|
|
||||||
*(uint32_t*)dest++ = *(uint32_t*)src++;
|
|
||||||
len -= 4;
|
|
||||||
}
|
|
||||||
while(len--) *(uint8_t*)dest++ = *(uint8_t*)src++;
|
|
||||||
}
|
|
||||||
|
|
||||||
int strlen(const char *txt){
|
|
||||||
int l = 0;
|
|
||||||
while(*txt++) ++l;
|
|
||||||
return l;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
void bufputchar(char ch){
|
void bufputchar(char ch){
|
||||||
if(blen > UARTBUFSZ-1){
|
if(blen > UARTBUFSZ-1){
|
||||||
sendbuf();
|
sendbuf();
|
||||||
@ -159,15 +148,14 @@ char *getnum(char *txt, uint32_t *N){
|
|||||||
return getdec(txt, N);
|
return getdec(txt, N);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parse `txt` to CAN_message
|
||||||
// send command, format: ID (hex/bin/dec) data bytes (up to 8 bytes, space-delimeted)
|
static CAN_message *parseCANmsg(char *txt){
|
||||||
TRUE_INLINE void sendCANcommand(char *txt){
|
static CAN_message canmsg;
|
||||||
SEND("CAN command with arguments:\n");
|
//SEND("CAN command with arguments:\n");
|
||||||
uint32_t N;
|
uint32_t N;
|
||||||
uint16_t ID = 0xffff;
|
|
||||||
char *n;
|
char *n;
|
||||||
uint8_t data[8];
|
|
||||||
int ctr = -1;
|
int ctr = -1;
|
||||||
|
canmsg.ID = 0xffff;
|
||||||
do{
|
do{
|
||||||
txt = omit_spaces(txt);
|
txt = omit_spaces(txt);
|
||||||
n = getnum(txt, &N);
|
n = getnum(txt, &N);
|
||||||
@ -175,37 +163,46 @@ TRUE_INLINE void sendCANcommand(char *txt){
|
|||||||
txt = n;
|
txt = n;
|
||||||
if(ctr == -1){
|
if(ctr == -1){
|
||||||
if(N > 0x7ff){
|
if(N > 0x7ff){
|
||||||
SEND("ID should be 11-bit number!");
|
SEND("ID should be 11-bit number!\n");
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
ID = (uint16_t)(N&0x7ff);
|
canmsg.ID = (uint16_t)(N&0x7ff);
|
||||||
SEND("ID="); printuhex(ID); newline();
|
SEND("ID="); printuhex(canmsg.ID); newline();
|
||||||
ctr = 0;
|
ctr = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(ctr > 7){
|
if(ctr > 7){
|
||||||
SEND("ONLY 8 data bytes allowed!");
|
SEND("ONLY 8 data bytes allowed!\n");
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(N > 0xff){
|
if(N > 0xff){
|
||||||
SEND("Every data portion is a byte!");
|
SEND("Every data portion is a byte!\n");
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
data[ctr++] = (uint8_t)(N&0xff);
|
canmsg.data[ctr++] = (uint8_t)(N&0xff);
|
||||||
printu(N); SEND(", hex: ");
|
//printu(N); SEND(", hex: ");
|
||||||
printuhex(N); newline();
|
//printuhex(N); newline();
|
||||||
}while(1);
|
}while(1);
|
||||||
if(*n){
|
/*if(*n){
|
||||||
SEND("\nUnusefull data: ");
|
SEND("\nUnusefull data: ");
|
||||||
SEND(n);
|
SEND(n);
|
||||||
|
}*/
|
||||||
|
if(canmsg.ID == 0xffff){
|
||||||
|
SEND("NO ID given, send nothing!\n");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
if(ID == 0xffff){
|
SEND("Message parsed OK\n");
|
||||||
SEND("NO ID given, send nothing!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sendbuf();
|
sendbuf();
|
||||||
N = 1000000;
|
canmsg.length = (uint8_t) ctr;
|
||||||
while(CAN_BUSY == can_send(data, (uint8_t)ctr, ID)){
|
return &canmsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// send command, format: ID (hex/bin/dec) data bytes (up to 8 bytes, space-delimeted)
|
||||||
|
TRUE_INLINE void sendCANcommand(char *txt){
|
||||||
|
CAN_message *msg = parseCANmsg(txt);
|
||||||
|
if(!msg) return;
|
||||||
|
uint32_t N = 1000000;
|
||||||
|
while(CAN_BUSY == can_send(msg->data, msg->length, msg->ID)){
|
||||||
if(--N == 0) break;
|
if(--N == 0) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -256,6 +253,7 @@ TRUE_INLINE void print_ign_buf(){
|
|||||||
SEND("Ignore buffer is empty");
|
SEND("Ignore buffer is empty");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
SEND("Ignored IDs:\n");
|
||||||
for(int i = 0; i < IgnSz; ++i){
|
for(int i = 0; i < IgnSz; ++i){
|
||||||
printu(i);
|
printu(i);
|
||||||
SEND(": ");
|
SEND(": ");
|
||||||
@ -437,6 +435,10 @@ void cmd_parser(char *txt, uint8_t isUSB){
|
|||||||
add_filter(txt + 1);
|
add_filter(txt + 1);
|
||||||
goto eof;
|
goto eof;
|
||||||
break;
|
break;
|
||||||
|
case 'F':
|
||||||
|
set_flood(parseCANmsg(txt + 1));
|
||||||
|
goto eof;
|
||||||
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
case 'S':
|
case 'S':
|
||||||
sendCANcommand(txt + 1);
|
sendCANcommand(txt + 1);
|
||||||
@ -471,6 +473,11 @@ void cmd_parser(char *txt, uint8_t isUSB){
|
|||||||
case 'p':
|
case 'p':
|
||||||
print_ign_buf();
|
print_ign_buf();
|
||||||
break;
|
break;
|
||||||
|
case 'P':
|
||||||
|
ShowMsgs = !ShowMsgs;
|
||||||
|
if(ShowMsgs) SEND("Resume\n");
|
||||||
|
else SEND("Pause\n");
|
||||||
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
SEND("Soft reset\n");
|
SEND("Soft reset\n");
|
||||||
sendbuf();
|
sendbuf();
|
||||||
@ -499,10 +506,12 @@ void cmd_parser(char *txt, uint8_t isUSB){
|
|||||||
"'C' - send dummy byte over CAN\n"
|
"'C' - send dummy byte over CAN\n"
|
||||||
"'d' - delete ignore list\n"
|
"'d' - delete ignore list\n"
|
||||||
"'f' - add/delete filter, format: bank# FIFO# mode(M/I) num0 [num1 [num2 [num3]]]\n"
|
"'f' - add/delete filter, format: bank# FIFO# mode(M/I) num0 [num1 [num2 [num3]]]\n"
|
||||||
|
"'F' - send/clear flood message: F ID byte0 ... byteN\n"
|
||||||
"'G' - get CAN address\n"
|
"'G' - get CAN address\n"
|
||||||
"'I' - reinit CAN (with new address)\n"
|
"'I' - reinit CAN (with new address)\n"
|
||||||
"'l' - list all active filters\n"
|
"'l' - list all active filters\n"
|
||||||
"'p' - print ignore buffer\n"
|
"'p' - print ignore buffer\n"
|
||||||
|
"'P' - pause/resume in packets displaying\n"
|
||||||
"'R' - software reset\n"
|
"'R' - software reset\n"
|
||||||
"'s/S' - send data over CAN: s ID byte0 .. byteN\n"
|
"'s/S' - send data over CAN: s ID byte0 .. byteN\n"
|
||||||
"'T' - gen time from start (ms)\n"
|
"'T' - gen time from start (ms)\n"
|
||||||
|
|||||||
@ -38,11 +38,12 @@
|
|||||||
|
|
||||||
#define newline() do{bufputchar('\n');}while(0)
|
#define newline() do{bufputchar('\n');}while(0)
|
||||||
// newline with buffer sending over USART
|
// newline with buffer sending over USART
|
||||||
#define NL() do{bufputchar('\n'); switchbuff(0); sendbuf();}while(0)
|
#define NL() do{bufputchar('\n'); register uint8_t o = switchbuff(3); sendbuf(); switchbuff(o);}while(0)
|
||||||
|
|
||||||
#define IGN_SIZE 10
|
#define IGN_SIZE 10
|
||||||
extern uint16_t Ignore_IDs[IGN_SIZE];
|
extern uint16_t Ignore_IDs[IGN_SIZE];
|
||||||
extern uint8_t IgnSz;
|
extern uint8_t IgnSz;
|
||||||
|
extern uint8_t ShowMsgs;
|
||||||
|
|
||||||
void cmd_parser(char *buf, uint8_t isUSB);
|
void cmd_parser(char *buf, uint8_t isUSB);
|
||||||
void addtobuf(const char *txt);
|
void addtobuf(const char *txt);
|
||||||
@ -50,13 +51,11 @@ void bufputchar(char ch);
|
|||||||
void printu(uint32_t val);
|
void printu(uint32_t val);
|
||||||
void printuhex(uint32_t val);
|
void printuhex(uint32_t val);
|
||||||
void sendbuf();
|
void sendbuf();
|
||||||
void switchbuff(uint8_t isUSB);
|
uint8_t switchbuff(uint8_t isUSB);
|
||||||
|
|
||||||
char *omit_spaces(char *buf);
|
char *omit_spaces(char *buf);
|
||||||
char *getnum(char *buf, uint32_t *N);
|
char *getnum(char *buf, uint32_t *N);
|
||||||
|
|
||||||
uint8_t isgood(uint16_t ID);
|
uint8_t isgood(uint16_t ID);
|
||||||
|
|
||||||
//int strlen(const char *txt);
|
|
||||||
//void memcpy(void *dest, const void *src, int len);
|
|
||||||
#endif // __PROTO_H__
|
#endif // __PROTO_H__
|
||||||
|
|||||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user