From c40e239b194e5696bd2261ae46a3e026b1e7fe71 Mon Sep 17 00:00:00 2001 From: eddyem Date: Sun, 24 Jun 2018 14:42:05 +0300 Subject: [PATCH] add more universal functions for reading/writing CAN --- F0-nolib/canbus/src/Makefile | 4 +- F0-nolib/canbus/src/can.c | 284 ++++++++++++++++++++++++++++----- F0-nolib/canbus/src/can.h | 22 ++- F0-nolib/canbus/src/canbus.bin | Bin 2948 -> 5648 bytes F0-nolib/canbus/src/hardware.h | 4 +- F0-nolib/canbus/src/main.c | 31 +++- F0-nolib/canbus/src/usart.c | 14 ++ F0-nolib/canbus/src/usart.h | 1 + 8 files changed, 311 insertions(+), 49 deletions(-) diff --git a/F0-nolib/canbus/src/Makefile b/F0-nolib/canbus/src/Makefile index aae0b4e..691a4d5 100644 --- a/F0-nolib/canbus/src/Makefile +++ b/F0-nolib/canbus/src/Makefile @@ -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 = ld/stm32f042k.ld @@ -55,7 +55,7 @@ LIB_DIR := $(INC_DIR)/ld ############################################################################### # C flags CFLAGS += -O2 -g -MD -D__thumb2__=1 -CFLAGS += -Wall -Wextra -Wshadow -Wimplicit-function-declaration +CFLAGS += -Wall -Werror -Wextra -Wshadow -Wimplicit-function-declaration CFLAGS += -Wredundant-decls $(INCLUDE) # -Wmissing-prototypes -Wstrict-prototypes CFLAGS += -fno-common -ffunction-sections -fdata-sections diff --git a/F0-nolib/canbus/src/can.c b/F0-nolib/canbus/src/can.c index 011d7db..49ff5f3 100644 --- a/F0-nolib/canbus/src/can.c +++ b/F0-nolib/canbus/src/can.c @@ -20,32 +20,91 @@ * MA 02110-1301, USA. * */ +#include // memcpy #include "can.h" #include "hardware.h" #include "usart.h" -#define CMD_TOGGLE (0xDA) -#define CAN_ID_MASK (0xFF70U) -#define CAN_ID1 (0x651U) -#define CAN_ID2 (0x652U) -#define FILTER_LIST (0) /* 0: filter mode = identifier mask, 1: filter mode = identifier list */ +#define CMD_TOGGLE (0xDA) +#define CAN_ID_MASK (0x7F8) +#define CAN_ID_PREFIX (0xAAA) +#define TARG_ID (CAN_ID_PREFIX & CAN_ID_MASK) -#define CAN_FLAG_GOTDUMMY (1) -static uint8_t CAN_addr = 255; +#define CAN_FLAG_GOTDUMMY (1) +// incoming message buffer size +#define CAN_INMESSAGE_SIZE (6) + +extern volatile uint32_t Tms; + +// circular buffer for received messages +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 CANID = 0xFFFF; static uint8_t CAN_flags = 0; +static uint32_t last_err_code = 0; +static CAN_status can_status = CAN_STOP; -// get CAN address data from GPIO pins -void readCANaddr(){ - CAN_addr = READ_CAN_INV_ADDR(); - CAN_addr = ~CAN_addr & 0x7; +static void can_process_fifo(uint8_t fifo_num); + +CAN_status CAN_get_status(){ + CAN_status st = can_status; + // give overrun message only once + if(st == CAN_FIFO_OVERRUN) can_status = CAN_READY; + return st; } -uint8_t getCANaddr(){ - return CAN_addr; +// push next message into buffer; return 1 if buffer overfull +static int CAN_messagebuf_push(CAN_message *msg){ + MSG("Try to push\n"); + if(first_free_idx == first_nonfree_idx) return 1; // no free space + memcpy(&messages[first_free_idx++], msg, sizeof(CAN_message)); + // need to roll? + if(first_free_idx == CAN_INMESSAGE_SIZE) first_free_idx = 0; + #ifdef EBUG + MSG("1st free: "); usart_putchar('0' + first_free_idx); newline(); + #endif + return 0; +} + +// pop message from buffer +CAN_message *CAN_messagebuf_pop(){ + if(first_nonfree_idx < 0) return NULL; + #ifdef EBUG + MSG("read from idx "); usart_putchar('0' + first_nonfree_idx); newline(); + #endif + CAN_message *msg = &messages[first_nonfree_idx++]; + if(first_nonfree_idx == CAN_INMESSAGE_SIZE) first_nonfree_idx = 0; + if(first_nonfree_idx == first_free_idx){ // buffer is empty - refresh it + first_nonfree_idx = -1; + first_free_idx = 0; + MSG("refresh buffer\n"); + } + return msg; +} + +// get CAN address data from GPIO pins +void readCANID(){ + uint8_t CAN_addr = READ_CAN_INV_ADDR(); + CAN_addr = ~CAN_addr & 0x7; + CANID = (CAN_ID_PREFIX & CAN_ID_MASK) | CAN_addr; +} + +uint16_t getCANID(){ + return CANID; +} + +void CAN_reinit(){ + readCANID(); + CAN->TSR |= CAN_TSR_ABRQ0 | CAN_TSR_ABRQ1 | CAN_TSR_ABRQ2; + RCC->APB1RSTR |= RCC_APB1RSTR_CANRST; + RCC->APB1RSTR &= ~RCC_APB1RSTR_CANRST; + CAN_setup(); } void CAN_setup(){ - if(CAN_addr == 255) readCANaddr(); + if(CANID == 0xFFFF) readCANID(); // Configure GPIO: PB8 - CAN_Rx, PB9 - CAN_Tx /* (1) Select AF mode (10) on PB8 and PB9 */ /* (2) AF4 for CAN signals */ @@ -59,23 +118,24 @@ void CAN_setup(){ /* (1) Enter CAN init mode to write the configuration */ /* (2) Wait the init mode entering */ /* (3) Exit sleep mode */ - /* (4) Loopback mode, set timing to 1Mb/s: BS1 = 4, BS2 = 3, prescaler = 6 */ + /* (4) Loopback mode, set timing to 100kb/s: BS1 = 4, BS2 = 3, prescaler = 60 */ /* (5) Leave init mode */ /* (6) Wait the init mode leaving */ /* (7) Enter filter init mode, (16-bit + mask, filter 0 for FIFO 0) */ /* (8) Acivate filter 0 */ /* (9) Identifier list mode */ - /* (11) Set the Id list */ - /* (12) Set the Id + mask (all bits of standard id will care) */ - /* (13) Leave filter init */ - /* (14) Set FIFO0 message pending IT enable */ + /* (10) Set the Id list */ + /* (12) Leave filter init */ + /* (13) Set error interrupts enable */ CAN->MCR |= CAN_MCR_INRQ; /* (1) */ while((CAN->MSR & CAN_MSR_INAK)!=CAN_MSR_INAK) /* (2) */ { /* add time out here for a robust application */ } CAN->MCR &=~ CAN_MCR_SLEEP; /* (3) */ - CAN->BTR |= CAN_BTR_LBKM | 2 << 20 | 3 << 16 | 5 << 0; /* (4) */ + CAN->MCR |= CAN_MCR_ABOM; + + CAN->BTR |= 2 << 20 | 3 << 16 | 59 << 0; /* (4) */ CAN->MCR &=~ CAN_MCR_INRQ; /* (5) */ while((CAN->MSR & CAN_MSR_INAK)==CAN_MSR_INAK) /* (6) */ { @@ -83,49 +143,191 @@ void CAN_setup(){ } CAN->FMR = CAN_FMR_FINIT; /* (7) */ CAN->FA1R = CAN_FA1R_FACT0; /* (8) */ - #if (FILTER_LIST) CAN->FM1R = CAN_FM1R_FBM0; /* (9) */ - CAN->sFilterRegister[0].FR1 = CAN_ID2 << 5 | CAN_ID1 << (16+5); /* (10) */ - #else - CAN->sFilterRegister[0].FR1 = CAN_ID1 << 5 | CAN_ID_MASK << 16; /* (11) */ - #endif /* FILTER_LIST */ + CAN->sFilterRegister[0].FR1 = CANID << 5; /* (10) */ CAN->FMR &=~ CAN_FMR_FINIT; /* (12) */ - CAN->IER |= CAN_IER_FMPIE0; /* (13) */ + CAN->IER |= CAN_IER_ERRIE | CAN_IER_FOVIE0 | CAN_IER_FOVIE1; /* (13) */ /* Configure IT */ /* (14) Set priority for CAN_IRQn */ /* (15) Enable CAN_IRQn */ - NVIC_SetPriority(CEC_CAN_IRQn, 0); /* (16) */ - NVIC_EnableIRQ(CEC_CAN_IRQn); /* (17) */ + NVIC_SetPriority(CEC_CAN_IRQn, 0); /* (14) */ + NVIC_EnableIRQ(CEC_CAN_IRQn); /* (15) */ + can_status = CAN_READY; } void can_proc(){ + if(last_err_code){ +#ifdef EBUG + MSG("Error, ESR="); + printu(last_err_code); + newline(); +#endif + last_err_code = 0; + } + // check for messages in FIFO0 & FIFO1 + if(CAN->RF0R & CAN_RF0R_FMP0){ + can_process_fifo(0); + } + if(CAN->RF1R & CAN_RF1R_FMP1){ + can_process_fifo(1); + } + if(CAN->ESR & (CAN_ESR_BOFF | CAN_ESR_EPVF | CAN_ESR_EWGF)){ // much errors - restart CAN BUS + MSG("bus-off, restarting\n"); + // request abort for all mailboxes + CAN->TSR |= CAN_TSR_ABRQ0 | CAN_TSR_ABRQ1 | CAN_TSR_ABRQ2; + // reset CAN bus + RCC->APB1RSTR |= RCC_APB1RSTR_CANRST; + RCC->APB1RSTR &= ~RCC_APB1RSTR_CANRST; + CAN_setup(); + } if(CAN_flags){ if(CAN_flags & CAN_FLAG_GOTDUMMY){ SEND("Got dummy message\n"); } CAN_flags = 0; } + LED_off(LED1); +#ifdef EBUG + static uint32_t esr, msr, tsr; + uint32_t msr_now = CAN->MSR & 0xf; + if(esr != CAN->ESR || msr != msr_now || tsr != CAN->TSR){ + MSG("Timestamp: "); + printu(Tms); + newline(); + } + if((CAN->ESR) != esr){ + usart_putchar(((CAN->ESR & CAN_ESR_BOFF) != 0) + '0'); + esr = CAN->ESR; + MSG("CAN->ESR: "); + printuhex(esr); newline(); + } + if(msr_now != msr){ + msr = msr_now; + MSG("CAN->MSR & 0xf: "); + printuhex(msr); newline(); + } + if(CAN->TSR != tsr){ + tsr = CAN->TSR; + MSG("CAN->TSR: "); + printuhex(tsr); newline(); + } +#endif +} + +CAN_status can_send(uint8_t *msg, uint8_t len, uint16_t target_id){ + uint8_t mailbox = 0; + // check first free mailbox + if(CAN->TSR & (CAN_TSR_TME)){ + mailbox = (CAN->TSR & CAN_TSR_CODE) >> 24; + #ifdef EBUG + MSG("select "); usart_putchar('0'+mailbox); SEND(" mailbox\n"); + #endif + }else{ // no free mailboxes + return CAN_BUSY; + } + CAN_TxMailBox_TypeDef *box = &CAN->sTxMailBox[mailbox]; + uint32_t lb = 0, hb = 0; + switch(len){ + case 8: + hb |= (uint32_t)msg[7] << 24; + case 7: + hb |= (uint32_t)msg[6] << 16; + case 6: + hb |= (uint32_t)msg[5] << 8; + case 5: + hb |= (uint32_t)msg[4]; + case 4: + lb |= (uint32_t)msg[3] << 24; + case 3: + lb |= (uint32_t)msg[2] << 16; + case 2: + lb |= (uint32_t)msg[1] << 8; + default: + lb |= (uint32_t)msg[0]; + } + box->TDLR = lb; + box->TDHR = hb; + box->TDTR = len; + box->TIR = (target_id & 0x7FF) << 21 | CAN_TI0R_TXRQ; + return CAN_OK; } void can_send_dummy(){ - if((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0){ /* check mailbox 0 is empty */ - CAN->sTxMailBox[0].TDTR = 1; /* fill data length = 1 */ - CAN->sTxMailBox[0].TDLR = CMD_TOGGLE; /* fill 8-bit data */ - CAN->sTxMailBox[0].TIR = (uint32_t)(CAN_ID1 << 21 | CAN_TI0R_TXRQ); /* fill Id field and request a transmission */ + uint8_t msg = CMD_TOGGLE; + if(CAN_OK != can_send(&msg, 1, TARG_ID)) SEND("Bus busy!\n"); + MSG("CAN->MSR: "); + printuhex(CAN->MSR); newline(); + MSG("CAN->TSR: "); + printuhex(CAN->TSR); newline(); + MSG("CAN->ESR: "); + printuhex(CAN->ESR); newline(); +} + +static void can_process_fifo(uint8_t fifo_num){ + if(fifo_num > 1) return; + LED_on(LED1); // Toggle LED1 + CAN_FIFOMailBox_TypeDef *box = &CAN->sFIFOMailBox[fifo_num]; + volatile uint32_t *RFxR = (fifo_num) ? &CAN->RF1R : &CAN->RF0R; + MSG("Receive, RDTR="); + #ifdef EBUG + printuhex(box->RDTR); + newline(); + #endif + // read all + while(*RFxR & CAN_RF0R_FMP0){ // amount of messages pending + // CAN_RDTxR: (16-31) - timestamp, (8-15) - filter match index, (0-3) - data length + /* TODO: check filter match index if more than one ID can receive */ + CAN_message msg; + uint8_t *dat = msg.data; + uint8_t len = box->RDTR & 0x7; + msg.length = len; + if(len){ // message can be without data + uint32_t hb = box->RDHR, lb = box->RDLR; + switch(len){ + case 8: + dat[7] = hb>>24; + case 7: + dat[6] = (hb>>16) & 0xff; + case 6: + dat[5] = (hb>>8) & 0xff; + case 5: + dat[4] = hb & 0xff; + case 4: + dat[3] = lb>>24; + case 3: + dat[2] = (lb>>16) & 0xff; + case 2: + dat[1] = (lb>>8) & 0xff; + case 1: + dat[0] = lb & 0xff; + } + } + if(CAN_messagebuf_push(&msg)) return; // error: buffer is full, try later + *RFxR |= CAN_RF0R_RFOM0; // release fifo for access to next message } + if(*RFxR & CAN_RF0R_FULL0) *RFxR &= ~CAN_RF0R_FULL0; } void cec_can_isr(){ - uint32_t CAN_ReceiveMessage = 0; - - if(CAN->RF0R & CAN_RF0R_FMP0){ /* check if a message is filtered and received by FIFO 0 */ - LED_blink(LED1); /* Toggle LED1 */ - CAN_ReceiveMessage = CAN->sFIFOMailBox[0].RDLR; /* read data */ - CAN->RF0R |= CAN_RF0R_RFOM0; /* release FIFO */ - if((CAN_ReceiveMessage & 0xFF) == CMD_TOGGLE){ - CAN_flags |= CAN_FLAG_GOTDUMMY; - } + if(CAN->RF0R & CAN_RF0R_FOVR0){ // FIFO overrun + CAN->RF0R &= ~CAN_RF0R_FOVR0; + can_status = CAN_FIFO_OVERRUN; + } + if(CAN->RF1R & CAN_RF1R_FOVR1){ + CAN->RF1R &= ~CAN_RF1R_FOVR1; + can_status = CAN_FIFO_OVERRUN; + } + #ifdef EBUG + if(can_status == CAN_FIFO_OVERRUN) MSG("fifo 0 overrun\n"); + #endif + if(CAN->MSR & CAN_MSR_ERRI){ // Error + CAN->MSR &= ~CAN_MSR_ERRI; + // request abort for problem mailbox + if(CAN->TSR & CAN_TSR_TERR0) CAN->TSR |= CAN_TSR_ABRQ0; + if(CAN->TSR & CAN_TSR_TERR1) CAN->TSR |= CAN_TSR_ABRQ1; + if(CAN->TSR & CAN_TSR_TERR2) CAN->TSR |= CAN_TSR_ABRQ2; + last_err_code = CAN->ESR; } } diff --git a/F0-nolib/canbus/src/can.h b/F0-nolib/canbus/src/can.h index 3e381a8..c21f7db 100644 --- a/F0-nolib/canbus/src/can.h +++ b/F0-nolib/canbus/src/can.h @@ -26,12 +26,30 @@ #include "hardware.h" -void readCANaddr(); -uint8_t getCANaddr(); +typedef struct{ + uint8_t data[8]; + uint8_t length; +} CAN_message; +typedef enum{ + CAN_STOP, + CAN_READY, + CAN_BUSY, + CAN_OK, + CAN_FIFO_OVERRUN +} CAN_status; + +CAN_status CAN_get_status(); + +void readCANID(); +uint16_t getCANID(); + +void CAN_reinit(); void CAN_setup(); void can_send_dummy(); void can_proc(); +CAN_message *CAN_messagebuf_pop(); + #endif // __CAN_H__ diff --git a/F0-nolib/canbus/src/canbus.bin b/F0-nolib/canbus/src/canbus.bin index 9a85c3c89f4f3849828be677efa2fa06bdee83a8..ef66d7b649c1c8c0fdc50643f3dfdc401ed1dc81 100755 GIT binary patch literal 5648 zcmb_AZBSd+mFMY6NJ!WS$sdyV@Y54EVBti7zhcL(tOpO!6E+5WjfE$9G6+9mV-&!# z$ZjW!8&7QGYzd?>NZrJfk8ajYJ1i4AnQpzM@lF~y-l+s}Ynvv^db-iLiKlAP4PZmG z=RUykG}&~2EHmfbbI&>V-t&F002456nV<Z7%sR}8aesZOco!d8oT zT4|BAuGtuE^-3>za5YL(4-u&hwn;KNHTJvlQR_MPfG|*1FVd~)Y1xWwt&XD)f~{Yq z(T>zqa|)7Y=P0(R^<=e?YdT1k3au90^I759YO_edD?aOvh&LoyI~(tDTSQ0>+=1kq zcTRiERt6yXtvRZ2CI-pZkV<_4$-Q%(LSt(b(ypHH=wyipWQjJUP9XK$o(!34lc{0b zA$Oy4cWd`9j2r4j^&b~PI|uoYFu)%XBK&b7%GdL4ZfejX3VgOS=t{dL@PB5rrBrF7 zrQfymdLtiZ_Xqk^I;GJWX8Wi!oRRbL{XQa1^+PiAE+nUBl!aSS$GI709vf3VVX$sS z&2P>U%?rWd7#)V>tyzuLfz;p1R9Kf0qqf~1rZ)J^ObC+i&Qa?b29m#-ea-cGoUGj~ zWJ_QliqWq_^2u2x&;yF%6)`BL;y*~x16JJW@8z9dO5|CcJS2aJvy1V0{58Zsi~S_Q zg|zltaXQ3pofvl5>1*5EQ5bJ{i9ca|xC)YeCjan^&gPh+9P66;2sJ&iNs z^*_u&@`*V}MrIEuAbIG{66*uVJ+{D|K<;7W_RJnYZt(8@M4?A7d%szh80AO#*+l+A zoV+sa=b!ERF5}J+Zioc?B0*{)iqm01OyF^CrS5LJ~oPb)z(bCWbhvuOm2rKMOQYr0Efg5f}s| z+);(uugzUoKSajPe}+7QYJWdG+c>Dc5O1={kNwIwz^u8Lw@xz5r($&heIv zv0+u8MLRaE?3);-`?oGt^l#0W7^eESYA1%FKQ%m``ESeT3A`oL$Y+Ndha;|SF@fKm zb9vYt9EYgM?tY$cPlpCbYYbCWxPh{NT)JMpzD-W$5!_92GcL;rMUp?;OPS$hQm0k$3p0lm<~M znwbg9VStB`0?%^U$5pa!PTt{wWbIwnlP*)Y$yCP8@z3+wR8zU;LC3Y+>YvKq1a_z! zlnO4`4GKM1+O6mQ6iQDU4jGhLTt~>D&~hcAHkFo(h!ne=yCyy=(oC+XL`%>H2CSbX z$oC`s-bDB?0qpg}r`?9MaYAP&6M#C4XhR4gj5hurZJ`BINLfh5Db^Asy?P1S7926x z*h5d+i?5kH*|OF*@5uGP;N@G`zoza0d*N?>1NAvSF=e_NhhH$K*$uI!ZhJ5*H0YvY z4hUXM+3Z2EX+6f^eAfM3-sMjTu>BzcYi=iqPtn1$KZ&375%0B4sLTPSP3=CNZV2d{ z24!ESkyEn~?t(1}Mh@?luzc^}9Rs+A5=^J$IpSr)dbjD6ex%p6Ggj&@!+VX~YT2}o zOIeL#eQOW*FAtI48Mdu+N0sq_j-#yOKD&T-gM1TZVK-OgTcnq9W|6k9XL0;pAm7b$ zRQ?U0MLNSV)!1959M^0-Y`| zUs_iRr@`BRH(YI)9aCAvWkOC+f3X*FeL%^E(-lrNqpnU5q$^KnYPnwS0^0|A&J=zz zfp;s~gxv$keVR%oQ>4F;7;Xg{AU#zTM&5tIB#GIg-}L{B-*j&Mh%u~l>xAbd9oLVy zqgLosngeLL&l1p7Yn>KfYU+`c{vw{c;9GK5IE;tjx!BC+NVY#(10#0q=1XFaEZl1E z&&aufo#Y(m#m6&Xvx^PF1lAqIo}b(+WCsY=Gg&W01C8pHu{sZHWw7VJC9kW&rnIP0 z&3zgP3mPp?xiJ^PPRAzHzV~tOV3^G;;Ds?N;@ggW$}0^9Ryxbwy}Uts&LzfNHQa(; zr{w*ef(bQqqh>G8xcE}RAVmZHt`)HdJ?8^X^=Kxk&Zm&`N??=6D4Jx=4$CV!o~-oY z%BN<^q?cS7xMq`>Crfx`2?z3bBmc3PwNkb)D4lUFiAALXk9}dEN?EE9rM9EgBQx`r z%6JU&9-C$E_YxG7nqubKu|`u=Jkr1R;HXDvKo~$7a*w=;V+<<5-Xk~V*)oCL7uWEnoSt5`z_}`OmI?#Nc@H@sPiHQ0-jz9O zVITm>e?`uR(~2Se#S1KD?Ss^mZ;mefb?ldNPkI{rQ7^(92=5~3*)@WGhDxk`C8 z%nnMVe@4ViLZKHZ_&SV;Iw2BRB3MNI#q5B^rHN^(^-P-E82Aon^eJt+;5!Lg$POv( zm*c-6HHkGr>h1TaCy52H>8PtkEH^<>`Uhcanwt(8PmTx7*h?tKdDm1NV}UhwfXHs9 zoEm%=gIyh0yA6^;RJ)C$8Z$Il2{xlhyMZx^(+MK`X9RNJO9)G`b~7MLqHIv4h*4$E zV(J4E=<(j7z$j{}SgfY_48^1gX6Y%;EFQq_rNG_=wvQ9|v|y$YazNo!5lzW1YZbB7 z)XOOv$S$Kikx|Kd&Bnr3r8_*VU$7upNq9u>MZVS+w$koJ3%}%({$r8ytKVj_oab5c z0=J0XR%>+_vYe;bI?!@`R`0<)ArD{3dF~siA(6-xa;q&3Sa+Y99l(cy0u zr~j@chp*LF?SqNoQ8T?)YfpVWV&%@MI{0pk^^O$-F zZ}-*I1_vC;(^?_<>P!JRO4`dG3OazySIng4{V@(K{p0oK!~Ea@s?-{!9{!$dI{sVC zR}w$cw_$|woETzisNVS#6xKpK;kO#U4)tD@mSB(x5qeAH04aen0)|@H<~4`_b3XzHaUR7wv64ud>7M z?+P3})M;gEx*1<{bBDjPlL>S(0I;vTvaX`OV$Ze`E!6Mg_uQKxkK3`6Ie4s-X$iEn zGwqN2J35XXW!jsXj&=B(ty+LX?OjY8Zsj}VFJ_MTk8Z&Yin3nbqoF8m&M*{v8a0Sddrqh44nQ1=O*4E7&?C$c*2Q#ROwxE)* z5Ba;uY;j|4L7lt^w?6Lc@Gop%P)~>*{=iW@g-9134|GY)QUCG9bw%2OeMF|q-`T|+ z_jNT%&FzO!i?u4y5XeW!L$DyMK+q#-5r)&|;dvY*2#t#$?`k3z0$Ey>$<5#C3ZD$m#O61?8A5@=6`# zJapB%?ReUJ{J!LEUgXu(*D-4tN2rBJ+~b$rTf65gYc~;IoxjN+cpS5&u6&Pd%DuH4 z9Ym#$Zl-p_CYqS2lYIFv z^PThm=ljn&);_wJhGt+l_`vrp;%UV3MJ)xe1Nif^{YS|kKW)N)Vd?+i{QDk_SkU{o zLLS>c{^7{xG3D-bL>o&4#E6>K4qSA_(`rOJlyJo(XkT}1T04lgo=vOep%Jk>5E&k^ z^MeqbRMW#_VtTM3)18ZO{j2&>@;DjRuaK~3x4cK$qu(J*3#%WJ=-^PghY<${NS87c z>7F+Rl!2bGY9p-<$dhVWgSPpSDo0c>Z&tzlvD%*ub1Z;asgc&20p{13efJ@lRxP1y z8=8W;xh=_{!}#1`bYu25W_yz%C;O?BE%NIM@;2(ZAy^(1`v#KArcINQs3bQ}NE?)K zsmM=xrX)q`mLjU4o$B^{@gOQ_R@YRE-tE7YmR`&TDJEWwo*-i)BVNv|(!i{*^+_!n z2=@$f7R+>w0y6Gu_ZiS$HaKi}7z@vp$au9P<^#gdrGh)ZQD`w%-0BtDj4gt{v?@tE z9lqprI4jLc^Ob(CEdk~}%v>t>SvVH}-zSKh2vn8zA@D*b9$@SX zg6~_j6g>1C<8OPyS&FZd5BnRk!FU68qMi}G(Mgd3m(1jH8*y(65`gQ8(wui<^y%rx zlt|uclZZJ1ANlqxKCQDTtTX*!mawsQ|=z$+KH4S7ZxDEUZWLyx~!e>HW@{3VdAQ1eKtx3 z;zjN%d0PyKBbhIwEQ=d#Eo&~ZtXh09UKYThX9!2hOdfU1RV#M0_89Hr`nphT0gcXC z1op=+(f5Q_?0BoXrBfDcDLxBRsUx21EnO`ex*; z^xr9RKG~gT4&KPx10o%#yMHYK-wZUK*IrNSKZLH6bNbAJy@fLvHzHzo9^rI=*6zlf z_Q0Ww(7L$P!IPN#ypU_g(StCL)qpK>O-e*2WEfm zDd_0jyM9fs73|okdY1iEf~foah464#n%GXdI&L=XJBb zb=k`}pzkqf+kfJN)$}Q%k2kDYn0bNC?A*C;*Z%!$@f^CqsQPQr diff --git a/F0-nolib/canbus/src/hardware.h b/F0-nolib/canbus/src/hardware.h index 322653b..56f152e 100644 --- a/F0-nolib/canbus/src/hardware.h +++ b/F0-nolib/canbus/src/hardware.h @@ -41,7 +41,9 @@ #define LED1_port GPIOC #define LED1_pin (1<<14) -#define LED_blink(x) pin_toggle(x ## _port, x ## _pin) +#define LED_blink(x) pin_toggle(x ## _port, x ## _pin) +#define LED_on(x) pin_clear(x ## _port, x ## _pin) +#define LED_off(x) pin_set(x ## _port, x ## _pin) // CAN address - PB14(0), PB15(1), PA8(2) diff --git a/F0-nolib/canbus/src/main.c b/F0-nolib/canbus/src/main.c index 11a0d59..a5f32f3 100644 --- a/F0-nolib/canbus/src/main.c +++ b/F0-nolib/canbus/src/main.c @@ -53,6 +53,8 @@ void iwdg_setup(){ int main(void){ uint32_t lastT = 0; + uint8_t ctr, len; + CAN_message *can_mesg; int L; char *txt; sysreset(); @@ -60,12 +62,13 @@ int main(void){ gpio_setup(); usart_setup(); iwdg_setup(); - readCANaddr(); + readCANID(); CAN_setup(); SEND("Greetings! My address is "); - printu(getCANaddr()); + printuhex(getCANID()); newline(); + if(RCC->CSR & RCC_CSR_IWDGRSTF){ // watchdog reset occured SEND("WDGRESET=1\n"); } @@ -81,6 +84,20 @@ int main(void){ lastT = Tms; } can_proc(); + if(CAN_get_status() == CAN_FIFO_OVERRUN){ + SEND("CAN bus fifo overrun occured!\n"); + } + can_mesg = CAN_messagebuf_pop(); + if(can_mesg){ // new data in buff + len = can_mesg->length; + SEND("got message, len: "); usart_putchar('0' + len); + SEND(", data: "); + for(ctr = 0; ctr < len; ++ctr){ + printuhex(can_mesg->data[ctr]); + usart_putchar(' '); + } + newline(); + } if(usartrx()){ // usart1 received data, store in in buffer L = usart_getline(&txt); char _1st = txt[0]; @@ -92,12 +109,19 @@ int main(void){ break; case 'G': SEND("Can address: "); - printu(getCANaddr()); + printuhex(getCANID()); newline(); break; case 'R': + SEND("Soft reset\n"); NVIC_SystemReset(); break; + case 'S': + CAN_reinit(); + SEND("Can address: "); + printuhex(getCANID()); + newline(); + break; case 'W': SEND("Wait for reboot\n"); while(1){nop();}; @@ -107,6 +131,7 @@ int main(void){ "'C' - send dummy byte over CAN\n" "'G' - get CAN address\n" "'R' - software reset\n" + "'S' - reinit CAN (with new address)\n" "'W' - test watchdog\n" ); break; diff --git a/F0-nolib/canbus/src/usart.c b/F0-nolib/canbus/src/usart.c index 47c5e44..64b6fc3 100644 --- a/F0-nolib/canbus/src/usart.c +++ b/F0-nolib/canbus/src/usart.c @@ -218,6 +218,20 @@ void printu(uint32_t val){ while(LINE_BUSY == usart_send_blocking(bufa, l+bpos)); } +// print 32bit unsigned int as hex +void printuhex(uint32_t val){ + SEND("0x"); + uint8_t *ptr = (uint8_t*)&val + 3; + int i, j; + for(i = 0; i < 4; ++i, --ptr){ + for(j = 1; j > -1; --j){ + uint8_t half = (*ptr >> (4*j)) & 0x0f; + if(half < 10) usart_putchar(half + '0'); + else usart_putchar(half - 10 + 'a'); + } + } +} + #if USARTNUM == 2 void dma1_channel4_5_isr(){ if(DMA1->ISR & DMA_ISR_TCIF4){ // Tx diff --git a/F0-nolib/canbus/src/usart.h b/F0-nolib/canbus/src/usart.h index f1d1d50..ae2da2e 100644 --- a/F0-nolib/canbus/src/usart.h +++ b/F0-nolib/canbus/src/usart.h @@ -56,5 +56,6 @@ TXstatus usart_send_blocking(const char *str, int len); void newline(); void usart_putchar(const char ch); void printu(uint32_t val); +void printuhex(uint32_t val); #endif // __USART_H__