From 6c21d9f91a45ba3a6456b418d77d19f7da54354e Mon Sep 17 00:00:00 2001 From: Edward Emelianov Date: Thu, 19 Feb 2026 23:11:11 +0300 Subject: [PATCH] CAN works --- F3:F303/InterfaceBoard/can.c | 14 ++-- F3:F303/InterfaceBoard/can.h | 2 +- F3:F303/InterfaceBoard/canproto.c | 61 ++++++++++++------ F3:F303/InterfaceBoard/canproto.h | 6 +- F3:F303/InterfaceBoard/main.c | 23 +------ F3:F303/InterfaceBoard/multiiface.bin | Bin 28024 -> 27996 bytes .../InterfaceBoard/multiiface.creator.user | 2 +- F3:F303/InterfaceBoard/version.inc | 4 +- 8 files changed, 62 insertions(+), 50 deletions(-) diff --git a/F3:F303/InterfaceBoard/can.c b/F3:F303/InterfaceBoard/can.c index d4a284b..b859b88 100644 --- a/F3:F303/InterfaceBoard/can.c +++ b/F3:F303/InterfaceBoard/can.c @@ -45,7 +45,7 @@ static CAN_message messages[CAN_INMESSAGE_SIZE]; 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 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 static uint8_t incrflood = 0; // ==1 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 static int CAN_messagebuf_push(CAN_message *msg){ - DBG("PUSH"); + //DBG("PUSH"); if(first_free_idx == first_nonfree_idx){ DBG("INBUF OVERFULL"); return 1; // no free space @@ -87,11 +87,11 @@ CAN_message *CAN_messagebuf_pop(){ first_nonfree_idx = -1; first_free_idx = 0; } - DBG("POP"); + //DBG("POP"); return msg; } -void CAN_reinit(uint16_t speed){ +void CAN_reinit(uint32_t speed){ DBG("CAN_reinit"); CAN->TSR |= CAN_TSR_ABRQ0 | CAN_TSR_ABRQ1 | CAN_TSR_ABRQ2; RCC->APB1RSTR |= RCC_APB1RSTR_CANRST; @@ -148,8 +148,10 @@ void CAN_setup(uint32_t speed){ if(tmout==0){ DBG("timeout!\n");} CAN->MCR &=~ CAN_MCR_SLEEP; /* (3) */ 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) */ 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) */ tmout = 10000; 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); }else if(incrflood && (Tms - lastFloodTime) >= floodT){ 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"); return CAN_BUSY; } -#ifdef EBUG +#if 0 DBGs("Send data. Len="); DBGs(u2str(len)); DBGs(", tagid="); DBGs(u2str(target_id)); DBGs(", data="); diff --git a/F3:F303/InterfaceBoard/can.h b/F3:F303/InterfaceBoard/can.h index 230bfbd..b76c603 100644 --- a/F3:F303/InterfaceBoard/can.h +++ b/F3:F303/InterfaceBoard/can.h @@ -50,7 +50,7 @@ typedef enum{ CAN_status CAN_get_status(); -void CAN_reinit(uint16_t speed); +void CAN_reinit(uint32_t speed); void CAN_setup(uint32_t speed); CAN_status CAN_send(uint8_t *msg, uint8_t len, uint16_t target_id); diff --git a/F3:F303/InterfaceBoard/canproto.c b/F3:F303/InterfaceBoard/canproto.c index 01cd407..a0e466a 100644 --- a/F3:F303/InterfaceBoard/canproto.c +++ b/F3:F303/InterfaceBoard/canproto.c @@ -77,8 +77,8 @@ static CAN_message *parseCANmsg(const char *txt){ return &canmsg; } -// USB_sendstr command, format: ID (hex/bin/dec) data bytes (up to 8 bytes, space-delimeted) -TRUE_INLINE void USB_sendstrCANcommand(char *txt){ +// Send command, format: ID (hex/bin/dec) data bytes (up to 8 bytes, space-delimeted) +TRUE_INLINE void CANcommand(char *txt){ if(CAN->MSR & CAN_MSR_INAK){ PRIstrn("CAN bus is off, try to restart it"); return; @@ -95,19 +95,20 @@ TRUE_INLINE void CANini(const char *txt){ uint32_t N; const char *n = getnum(txt, &N); if(txt == n){ - PRIstr("No speed given"); + PRIstr("CANspeed="); + PRIstrn(u2str(CAN_speed())); return; } - if(N < 50){ - PRIstr("Lowest speed is 50kbps"); + if(N < CAN_MIN_SPEED){ + PRIstrn("Speed is too low"); return; - }else if(N > 3000){ - PRIstr("Highest speed is 3000kbps"); + }else if(N > CAN_MAX_SPEED){ + PRIstrn("Speed is too large"); return; } - CAN_reinit((uint16_t)N); + CAN_reinit(N); PRIstr("Reinit CAN bus with speed "); - printu(N); PRIstrn("kbps"); + printu(N); PRIn(); } 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); 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(){ @@ -136,7 +137,7 @@ TRUE_INLINE void print_ign_buf(){ PRIstrn("Ignore buffer is empty"); return; } - PRIstrn("Ignored IDs:"); + PRIstr("Ignored IDs:"); for(int i = 0; i < IgnSz; ++i){ printu(i); PRIstr(": "); @@ -191,7 +192,7 @@ TRUE_INLINE void list_filters(){ PRIstr(", MASK="); printID(CAN->sFilterRegister[ctr].FR2 >> 16); } } - PRIstr("\n"); + PRIn(); } fa >>= 1; ++ctr; @@ -203,11 +204,8 @@ TRUE_INLINE void setfloodt(const char *s){ uint32_t N; s = omit_spaces(s); const char *n = getnum(s, &N); - if(s == n){ - PRIstrn("t="); PRIstrn(u2str(floodT)); - return; - } - floodT = N; + if(s != n) floodT = N; + PRIstr("t="); PRIstrn(u2str(floodT)); } /** @@ -364,7 +362,7 @@ void CANcmd_parser(char *txt){ break; case 's': case 'S': - USB_sendstrCANcommand(txt); + CANcommand(txt); return; break; case 't': @@ -389,6 +387,8 @@ void CANcmd_parser(char *txt){ break; case 'I': CAN_reinit(0); + PRIstr("CANspeed="); + PRIstrn(u2str(CAN_speed())); break; case 'l': list_filters(); @@ -422,3 +422,28 @@ uint8_t CANsoftFilter(uint16_t ID){ if(Ignore_IDs[i] == ID) return 0; 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); + } + } + } +} diff --git a/F3:F303/InterfaceBoard/canproto.h b/F3:F303/InterfaceBoard/canproto.h index a89b05d..da3c7c0 100644 --- a/F3:F303/InterfaceBoard/canproto.h +++ b/F3:F303/InterfaceBoard/canproto.h @@ -34,6 +34,10 @@ #endif // CANPRIVATE__ -extern uint8_t CANShowMsgs; // show CAN messages flag +void canproto_process(); void CANcmd_parser(char *txt); +/* +extern uint8_t CANShowMsgs; // show CAN messages flag + uint8_t CANsoftFilter(uint16_t ID); +*/ diff --git a/F3:F303/InterfaceBoard/main.c b/F3:F303/InterfaceBoard/main.c index fc94d4b..89447ad 100644 --- a/F3:F303/InterfaceBoard/main.c +++ b/F3:F303/InterfaceBoard/main.c @@ -64,31 +64,12 @@ int main(void){ if(l) USB_send(i, (uint8_t*)inbuff, l); }*/ 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); if(l < 0) USB_sendstr(ICAN, "ERROR: USB buffer overflow or string was too long\n"); else if(l) CANcmd_parser(inbuff); + canproto_process(); } + if(Config_mode && CDCready[ICFG]){ /*if(Tms - ctr > 4999){ ctr = Tms; diff --git a/F3:F303/InterfaceBoard/multiiface.bin b/F3:F303/InterfaceBoard/multiiface.bin index 01e7c0af2ba016fc279a1857fb75c354bfc74bb1..3ac4516b644cf3248a17ce57eab5d101dbd82267 100755 GIT binary patch delta 8160 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 - + EnvironmentId diff --git a/F3:F303/InterfaceBoard/version.inc b/F3:F303/InterfaceBoard/version.inc index d09273c..30fb985 100644 --- a/F3:F303/InterfaceBoard/version.inc +++ b/F3:F303/InterfaceBoard/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "145" -#define BUILD_DATE "2026-02-18" +#define BUILD_NUMBER "151" +#define BUILD_DATE "2026-02-19"