mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 10:45:11 +03:00
Add flood & pause commands
This commit is contained in:
parent
360de69497
commit
e51a45040b
@ -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
|
||||
|
||||
@ -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){
|
||||
|
||||
@ -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__
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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.
Loading…
x
Reference in New Issue
Block a user