mirror of
https://github.com/eddyem/stm32samples.git
synced 2026-02-28 03:44:30 +03:00
CAN works
This commit is contained in:
@@ -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=");
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
*/
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Binary file not shown.
@@ -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>
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
#define BUILD_NUMBER "145"
|
#define BUILD_NUMBER "151"
|
||||||
#define BUILD_DATE "2026-02-18"
|
#define BUILD_DATE "2026-02-19"
|
||||||
|
|||||||
Reference in New Issue
Block a user