CAN works

This commit is contained in:
Edward Emelianov
2026-02-19 23:11:11 +03:00
parent 80c894517e
commit 6c21d9f91a
8 changed files with 62 additions and 50 deletions

View File

@@ -45,7 +45,7 @@
static CAN_message messages[CAN_INMESSAGE_SIZE]; static CAN_message messages[CAN_INMESSAGE_SIZE];
static uint8_t first_free_idx = 0; // index of first empty cell static uint8_t first_free_idx = 0; // index of first empty cell
static int8_t first_nonfree_idx = -1; // index of first data cell static int8_t first_nonfree_idx = -1; // index of first data cell
static uint16_t oldspeed = 100; // speed of last init static uint32_t oldspeed = 100000; // speed of last init
uint32_t floodT = FLOOD_PERIOD_MS; // flood period in ms uint32_t floodT = FLOOD_PERIOD_MS; // flood period in ms
static uint8_t incrflood = 0; // ==1 for incremental flooding static uint8_t incrflood = 0; // ==1 for incremental flooding
static uint32_t incrmessagectr = 0; // counter for incremental flooding static uint32_t incrmessagectr = 0; // counter for incremental flooding
@@ -66,7 +66,7 @@ CAN_status CAN_get_status(){
// push next message into buffer; return 1 if buffer overfull // push next message into buffer; return 1 if buffer overfull
static int CAN_messagebuf_push(CAN_message *msg){ static int CAN_messagebuf_push(CAN_message *msg){
DBG("PUSH"); //DBG("PUSH");
if(first_free_idx == first_nonfree_idx){ if(first_free_idx == first_nonfree_idx){
DBG("INBUF OVERFULL"); DBG("INBUF OVERFULL");
return 1; // no free space return 1; // no free space
@@ -87,11 +87,11 @@ CAN_message *CAN_messagebuf_pop(){
first_nonfree_idx = -1; first_nonfree_idx = -1;
first_free_idx = 0; first_free_idx = 0;
} }
DBG("POP"); //DBG("POP");
return msg; return msg;
} }
void CAN_reinit(uint16_t speed){ void CAN_reinit(uint32_t speed){
DBG("CAN_reinit"); DBG("CAN_reinit");
CAN->TSR |= CAN_TSR_ABRQ0 | CAN_TSR_ABRQ1 | CAN_TSR_ABRQ2; CAN->TSR |= CAN_TSR_ABRQ0 | CAN_TSR_ABRQ1 | CAN_TSR_ABRQ2;
RCC->APB1RSTR |= RCC_APB1RSTR_CANRST; RCC->APB1RSTR |= RCC_APB1RSTR_CANRST;
@@ -148,8 +148,10 @@ void CAN_setup(uint32_t speed){
if(tmout==0){ DBG("timeout!\n");} if(tmout==0){ DBG("timeout!\n");}
CAN->MCR &=~ CAN_MCR_SLEEP; /* (3) */ CAN->MCR &=~ CAN_MCR_SLEEP; /* (3) */
CAN->MCR |= CAN_MCR_ABOM; /* allow automatically bus-off */ CAN->MCR |= CAN_MCR_ABOM; /* allow automatically bus-off */
DBG("new speed:"); DBGs(u2str(speed)); DBGn();
CAN->BTR = (CAN_TBS2-1) << 20 | (CAN_TBS1-1) << 16 | (CAN_BIT_OSC/speed - 1); /* (4) */ CAN->BTR = (CAN_TBS2-1) << 20 | (CAN_TBS1-1) << 16 | (CAN_BIT_OSC/speed - 1); /* (4) */
oldspeed = CAN_BIT_OSC/(uint32_t)((CAN->BTR & CAN_BTR_BRP) + 1); oldspeed = CAN_BIT_OSC/(uint32_t)((CAN->BTR & CAN_BTR_BRP) + 1);
DBG("saved sped:"); DBGs(u2str(oldspeed)); DBGn();
CAN->MCR &= ~CAN_MCR_INRQ; /* (5) */ CAN->MCR &= ~CAN_MCR_INRQ; /* (5) */
tmout = 10000; tmout = 10000;
while(CAN->MSR & CAN_MSR_INAK) /* (6) */ while(CAN->MSR & CAN_MSR_INAK) /* (6) */
@@ -232,7 +234,7 @@ void CAN_proc(){
CAN_send(flood_msg->data, flood_msg->length, flood_msg->ID); CAN_send(flood_msg->data, flood_msg->length, flood_msg->ID);
}else if(incrflood && (Tms - lastFloodTime) >= floodT){ }else if(incrflood && (Tms - lastFloodTime) >= floodT){
lastFloodTime = Tms; lastFloodTime = Tms;
if(CAN_OK == CAN_send((uint8_t*)&incrmessagectr, 4, flood_msg->ID)) ++incrmessagectr; if(CAN_OK == CAN_send((uint8_t*)&incrmessagectr, 4, loc_flood_msg.ID)) ++incrmessagectr;
} }
} }
@@ -245,7 +247,7 @@ CAN_status CAN_send(uint8_t *msg, uint8_t len, uint16_t target_id){
DBG("No free mailboxes"); DBG("No free mailboxes");
return CAN_BUSY; return CAN_BUSY;
} }
#ifdef EBUG #if 0
DBGs("Send data. Len="); DBGs(u2str(len)); DBGs("Send data. Len="); DBGs(u2str(len));
DBGs(", tagid="); DBGs(u2str(target_id)); DBGs(", tagid="); DBGs(u2str(target_id));
DBGs(", data="); DBGs(", data=");

View File

@@ -50,7 +50,7 @@ typedef enum{
CAN_status CAN_get_status(); CAN_status CAN_get_status();
void CAN_reinit(uint16_t speed); void CAN_reinit(uint32_t speed);
void CAN_setup(uint32_t speed); void CAN_setup(uint32_t speed);
CAN_status CAN_send(uint8_t *msg, uint8_t len, uint16_t target_id); CAN_status CAN_send(uint8_t *msg, uint8_t len, uint16_t target_id);

View File

@@ -77,8 +77,8 @@ static CAN_message *parseCANmsg(const char *txt){
return &canmsg; return &canmsg;
} }
// USB_sendstr command, format: ID (hex/bin/dec) data bytes (up to 8 bytes, space-delimeted) // Send command, format: ID (hex/bin/dec) data bytes (up to 8 bytes, space-delimeted)
TRUE_INLINE void USB_sendstrCANcommand(char *txt){ TRUE_INLINE void CANcommand(char *txt){
if(CAN->MSR & CAN_MSR_INAK){ if(CAN->MSR & CAN_MSR_INAK){
PRIstrn("CAN bus is off, try to restart it"); PRIstrn("CAN bus is off, try to restart it");
return; return;
@@ -95,19 +95,20 @@ TRUE_INLINE void CANini(const char *txt){
uint32_t N; uint32_t N;
const char *n = getnum(txt, &N); const char *n = getnum(txt, &N);
if(txt == n){ if(txt == n){
PRIstr("No speed given"); PRIstr("CANspeed=");
PRIstrn(u2str(CAN_speed()));
return; return;
} }
if(N < 50){ if(N < CAN_MIN_SPEED){
PRIstr("Lowest speed is 50kbps"); PRIstrn("Speed is too low");
return; return;
}else if(N > 3000){ }else if(N > CAN_MAX_SPEED){
PRIstr("Highest speed is 3000kbps"); PRIstrn("Speed is too large");
return; return;
} }
CAN_reinit((uint16_t)N); CAN_reinit(N);
PRIstr("Reinit CAN bus with speed "); PRIstr("Reinit CAN bus with speed ");
printu(N); PRIstrn("kbps"); printu(N); PRIn();
} }
TRUE_INLINE void addIGN(const char *txt){ TRUE_INLINE void addIGN(const char *txt){
@@ -128,7 +129,7 @@ TRUE_INLINE void addIGN(const char *txt){
} }
Ignore_IDs[IgnSz++] = (uint16_t)(N & 0x7ff); Ignore_IDs[IgnSz++] = (uint16_t)(N & 0x7ff);
PRIstr("Added ID "); printu(N); PRIstr("Added ID "); printu(N);
PRIstrn("\nIgn buffer size: "); PRIstrn(u2str(IgnSz)); PRIstr("\nIgn buffer size: "); PRIstrn(u2str(IgnSz));
} }
TRUE_INLINE void print_ign_buf(){ TRUE_INLINE void print_ign_buf(){
@@ -136,7 +137,7 @@ TRUE_INLINE void print_ign_buf(){
PRIstrn("Ignore buffer is empty"); PRIstrn("Ignore buffer is empty");
return; return;
} }
PRIstrn("Ignored IDs:"); PRIstr("Ignored IDs:");
for(int i = 0; i < IgnSz; ++i){ for(int i = 0; i < IgnSz; ++i){
printu(i); printu(i);
PRIstr(": "); PRIstr(": ");
@@ -191,7 +192,7 @@ TRUE_INLINE void list_filters(){
PRIstr(", MASK="); printID(CAN->sFilterRegister[ctr].FR2 >> 16); PRIstr(", MASK="); printID(CAN->sFilterRegister[ctr].FR2 >> 16);
} }
} }
PRIstr("\n"); PRIn();
} }
fa >>= 1; fa >>= 1;
++ctr; ++ctr;
@@ -203,11 +204,8 @@ TRUE_INLINE void setfloodt(const char *s){
uint32_t N; uint32_t N;
s = omit_spaces(s); s = omit_spaces(s);
const char *n = getnum(s, &N); const char *n = getnum(s, &N);
if(s == n){ if(s != n) floodT = N;
PRIstrn("t="); PRIstrn(u2str(floodT)); PRIstr("t="); PRIstrn(u2str(floodT));
return;
}
floodT = N;
} }
/** /**
@@ -364,7 +362,7 @@ void CANcmd_parser(char *txt){
break; break;
case 's': case 's':
case 'S': case 'S':
USB_sendstrCANcommand(txt); CANcommand(txt);
return; return;
break; break;
case 't': case 't':
@@ -389,6 +387,8 @@ void CANcmd_parser(char *txt){
break; break;
case 'I': case 'I':
CAN_reinit(0); CAN_reinit(0);
PRIstr("CANspeed=");
PRIstrn(u2str(CAN_speed()));
break; break;
case 'l': case 'l':
list_filters(); list_filters();
@@ -422,3 +422,28 @@ uint8_t CANsoftFilter(uint16_t ID){
if(Ignore_IDs[i] == ID) return 0; if(Ignore_IDs[i] == ID) return 0;
return 1; return 1;
} }
// process incoming USB and CAN messages
void canproto_process(){
CAN_proc();
if(CAN_get_status() == CAN_FIFO_OVERRUN){
USB_sendstr(ICAN, "CAN bus fifo overrun occured!\n");
}
CAN_message *can_mesg;
while((can_mesg = CAN_messagebuf_pop())){
if(can_mesg && CANsoftFilter(can_mesg->ID)){
if(CANShowMsgs){ // display message content
IWDG->KR = IWDG_REFRESH;
uint8_t len = can_mesg->length;
USB_sendstr(ICAN, u2str(Tms));
USB_sendstr(ICAN, " #");
USB_sendstr(ICAN, uhex2str(can_mesg->ID));
for(uint8_t i = 0; i < len; ++i){
USB_putbyte(ICAN, ' ');
USB_sendstr(ICAN, uhex2str(can_mesg->data[i]));
}
newline(ICAN);
}
}
}
}

View File

@@ -34,6 +34,10 @@
#endif // CANPRIVATE__ #endif // CANPRIVATE__
extern uint8_t CANShowMsgs; // show CAN messages flag void canproto_process();
void CANcmd_parser(char *txt); void CANcmd_parser(char *txt);
/*
extern uint8_t CANShowMsgs; // show CAN messages flag
uint8_t CANsoftFilter(uint16_t ID); uint8_t CANsoftFilter(uint16_t ID);
*/

View File

@@ -64,31 +64,12 @@ int main(void){
if(l) USB_send(i, (uint8_t*)inbuff, l); if(l) USB_send(i, (uint8_t*)inbuff, l);
}*/ }*/
if(CDCready[ICAN]){ if(CDCready[ICAN]){
CAN_proc();
if(CAN_get_status() == CAN_FIFO_OVERRUN){
USB_sendstr(ICAN, "CAN bus fifo overrun occured!\n");
}
CAN_message *can_mesg;
while((can_mesg = CAN_messagebuf_pop())){
if(can_mesg && CANsoftFilter(can_mesg->ID)){
if(CANShowMsgs){ // display message content
IWDG->KR = IWDG_REFRESH;
uint8_t len = can_mesg->length;
USB_sendstr(ICAN, u2str(Tms));
USB_sendstr(ICAN, " #");
USB_sendstr(ICAN, u2str(can_mesg->ID));
for(uint8_t i = 0; i < len; ++i){
USB_putbyte(ICAN, ' ');
USB_sendstr(ICAN, u2str(can_mesg->data[i]));
}
newline(ICAN);
}
}
}
int l = USB_receivestr(ICAN, inbuff, MAXSTRLEN); int l = USB_receivestr(ICAN, inbuff, MAXSTRLEN);
if(l < 0) USB_sendstr(ICAN, "ERROR: USB buffer overflow or string was too long\n"); if(l < 0) USB_sendstr(ICAN, "ERROR: USB buffer overflow or string was too long\n");
else if(l) CANcmd_parser(inbuff); else if(l) CANcmd_parser(inbuff);
canproto_process();
} }
if(Config_mode && CDCready[ICFG]){ if(Config_mode && CDCready[ICFG]){
/*if(Tms - ctr > 4999){ /*if(Tms - ctr > 4999){
ctr = Tms; ctr = Tms;

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject> <!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 18.0.2, 2026-02-18T22:53:46. --> <!-- Written by QtCreator 18.0.2, 2026-02-19T23:09:57. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>

View File

@@ -1,2 +1,2 @@
#define BUILD_NUMBER "145" #define BUILD_NUMBER "151"
#define BUILD_DATE "2026-02-18" #define BUILD_DATE "2026-02-19"