Add flood & pause commands

This commit is contained in:
eddyem 2020-04-13 21:21:40 +03:00
parent 360de69497
commit e51a45040b
7 changed files with 94 additions and 64 deletions

View File

@ -8,7 +8,7 @@ MCU = F042x6
# hardware definitions
DEFS += -DUSARTNUM=1
#DEFS += -DCHECK_TMOUT
DEFS += -DEBUG
#DEFS += -DEBUG
# change this linking script depending on particular MCU model,
# for example, if you have STM32F103VBT6, you should write:
LDSCRIPT = stm32f042k.ld

View File

@ -41,6 +41,9 @@ static CAN_status can_status = CAN_STOP;
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 st = can_status;
// give overrun message only once
@ -205,9 +208,9 @@ void can_proc(){
if(CAN->RF1R & CAN_RF1R_FMP1){
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
switchbuff(0);
SEND("\nToo much errors, restarting!\n");
SEND("\nToo much errors, restarting CAN!\n");
SEND("Receive error counter: ");
printu((CAN->ESR & CAN_ESR_REC)>>24);
SEND("\nTransmit error counter: ");
@ -236,6 +239,11 @@ void can_proc(){
RCC->APB1RSTR &= ~RCC_APB1RSTR_CANRST;
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
static uint32_t esr, msr, tsr;
uint32_t msr_now = CAN->MSR & 0xf;
@ -333,6 +341,14 @@ void can_send_broadcast(){
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){
if(fifo_num > 1) return;
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;
msg.length = len;
msg.ID = box->RIR >> 21;
msg.filterNo = (box->RDTR >> 8) & 0xff;
msg.fifoNum = fifo_num;
//msg.filterNo = (box->RDTR >> 8) & 0xff;
//msg.fifoNum = fifo_num;
if(len){ // message can be without data
uint32_t hb = box->RDHR, lb = box->RDLR;
switch(len){

View File

@ -28,6 +28,8 @@
// amount of filter banks in STM32F0
#define STM32F0FBANKNO 28
// flood period in milliseconds
#define FLOOD_PERIOD_MS 5
// simple 1-byte commands
#define CMD_TOGGLE (0xDA)
@ -48,8 +50,8 @@
typedef struct{
uint8_t data[8]; // up to 8 bytes of data
uint8_t length; // data length
uint8_t filterNo; // filter number
uint8_t fifoNum; // message FIFO number
//uint8_t filterNo; // filter number
//uint8_t fifoNum; // message FIFO number
uint16_t ID; // ID of receiver
} CAN_message;
@ -76,4 +78,6 @@ void can_proc();
CAN_message *CAN_messagebuf_pop();
void set_flood(CAN_message *msg);
#endif // __CAN_H__

View File

@ -105,14 +105,15 @@ int main(void){
switchbuff(0);
SEND("Greetings! My address is ");
printuhex(getCANID());
NL();
newline();
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
SEND("SOFTRESET=1\n"); NL();
SEND("SOFTRESET=1\n");
}
sendbuf();
RCC->CSR |= RCC_CSR_RMVF; // remove reset flags
iwdg_setup();
USB_setup();
@ -127,26 +128,27 @@ int main(void){
can_proc();
usb_proc();
if(CAN_get_status() == CAN_FIFO_OVERRUN){
switchbuff(3);
register uint8_t o = switchbuff(3);
SEND("CAN bus fifo overrun occured!\n");
newline(); sendbuf();
sendbuf(); switchbuff(o);
}
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;
switchbuff(3);
SEND("got message, ID=");
printu(Tms);
SEND(" #");
printuhex(can_mesg->ID);
SEND(", filter #");
/*SEND(", filter #");
printu(can_mesg->filterNo);
SEND(", FIFO #");
printu(can_mesg->fifoNum);
SEND(", len=");
printu(can_mesg->fifoNum);*/
/*SEND(", len=");
printu(len);
SEND(", data: ");
SEND(", data: ");*/
for(ctr = 0; ctr < len; ++ctr){
printuhex(can_mesg->data[ctr]);
SEND(" ");
printuhex(can_mesg->data[ctr]);
}
newline(); sendbuf();
}

View File

@ -30,6 +30,7 @@
extern volatile uint8_t canerror;
uint8_t ShowMsgs = 07;
uint16_t Ignore_IDs[IGN_SIZE];
uint8_t IgnSz = 0;
static char buff[UARTBUFSZ+1], *bptr = buff;
@ -49,25 +50,13 @@ void sendbuf(){
}
// 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;
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){
if(blen > UARTBUFSZ-1){
sendbuf();
@ -159,15 +148,14 @@ char *getnum(char *txt, uint32_t *N){
return getdec(txt, N);
}
// send command, format: ID (hex/bin/dec) data bytes (up to 8 bytes, space-delimeted)
TRUE_INLINE void sendCANcommand(char *txt){
SEND("CAN command with arguments:\n");
// parse `txt` to CAN_message
static CAN_message *parseCANmsg(char *txt){
static CAN_message canmsg;
//SEND("CAN command with arguments:\n");
uint32_t N;
uint16_t ID = 0xffff;
char *n;
uint8_t data[8];
int ctr = -1;
canmsg.ID = 0xffff;
do{
txt = omit_spaces(txt);
n = getnum(txt, &N);
@ -175,37 +163,46 @@ TRUE_INLINE void sendCANcommand(char *txt){
txt = n;
if(ctr == -1){
if(N > 0x7ff){
SEND("ID should be 11-bit number!");
return;
SEND("ID should be 11-bit number!\n");
return NULL;
}
ID = (uint16_t)(N&0x7ff);
SEND("ID="); printuhex(ID); newline();
canmsg.ID = (uint16_t)(N&0x7ff);
SEND("ID="); printuhex(canmsg.ID); newline();
ctr = 0;
continue;
}
if(ctr > 7){
SEND("ONLY 8 data bytes allowed!");
return;
SEND("ONLY 8 data bytes allowed!\n");
return NULL;
}
if(N > 0xff){
SEND("Every data portion is a byte!");
return;
SEND("Every data portion is a byte!\n");
return NULL;
}
data[ctr++] = (uint8_t)(N&0xff);
printu(N); SEND(", hex: ");
printuhex(N); newline();
canmsg.data[ctr++] = (uint8_t)(N&0xff);
//printu(N); SEND(", hex: ");
//printuhex(N); newline();
}while(1);
if(*n){
/*if(*n){
SEND("\nUnusefull data: ");
SEND(n);
}*/
if(canmsg.ID == 0xffff){
SEND("NO ID given, send nothing!\n");
return NULL;
}
if(ID == 0xffff){
SEND("NO ID given, send nothing!");
return;
}
SEND("Message parsed OK\n");
sendbuf();
N = 1000000;
while(CAN_BUSY == can_send(data, (uint8_t)ctr, ID)){
canmsg.length = (uint8_t) ctr;
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;
}
}
@ -256,6 +253,7 @@ TRUE_INLINE void print_ign_buf(){
SEND("Ignore buffer is empty");
return;
}
SEND("Ignored IDs:\n");
for(int i = 0; i < IgnSz; ++i){
printu(i);
SEND(": ");
@ -437,6 +435,10 @@ void cmd_parser(char *txt, uint8_t isUSB){
add_filter(txt + 1);
goto eof;
break;
case 'F':
set_flood(parseCANmsg(txt + 1));
goto eof;
break;
case 's':
case 'S':
sendCANcommand(txt + 1);
@ -471,6 +473,11 @@ void cmd_parser(char *txt, uint8_t isUSB){
case 'p':
print_ign_buf();
break;
case 'P':
ShowMsgs = !ShowMsgs;
if(ShowMsgs) SEND("Resume\n");
else SEND("Pause\n");
break;
case 'R':
SEND("Soft reset\n");
sendbuf();
@ -499,10 +506,12 @@ void cmd_parser(char *txt, uint8_t isUSB){
"'C' - send dummy byte over CAN\n"
"'d' - delete ignore list\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"
"'I' - reinit CAN (with new address)\n"
"'l' - list all active filters\n"
"'p' - print ignore buffer\n"
"'P' - pause/resume in packets displaying\n"
"'R' - software reset\n"
"'s/S' - send data over CAN: s ID byte0 .. byteN\n"
"'T' - gen time from start (ms)\n"

View File

@ -38,11 +38,12 @@
#define newline() do{bufputchar('\n');}while(0)
// 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
extern uint16_t Ignore_IDs[IGN_SIZE];
extern uint8_t IgnSz;
extern uint8_t ShowMsgs;
void cmd_parser(char *buf, uint8_t isUSB);
void addtobuf(const char *txt);
@ -50,13 +51,11 @@ void bufputchar(char ch);
void printu(uint32_t val);
void printuhex(uint32_t val);
void sendbuf();
void switchbuff(uint8_t isUSB);
uint8_t switchbuff(uint8_t isUSB);
char *omit_spaces(char *buf);
char *getnum(char *buf, uint32_t *N);
uint8_t isgood(uint16_t ID);
//int strlen(const char *txt);
//void memcpy(void *dest, const void *src, int len);
#endif // __PROTO_H__

Binary file not shown.