/******************************************************************************* * the includes ******************************************************************************/ #include "Uart2CanDiagApp.h" #include #include #include "CanDrv.h" #include "uartapp.h" /******************************************************************************* * the defines ******************************************************************************/ #define U2CD_TX_BUF_SIZE 2050 #define U2CD_RX_BUF_SIZE 128 #define N_Bs 150 #define N_As 70 #define P2_SERVER 150 /******************************************************************************* * the typedefs ******************************************************************************/ typedef enum { U2CD_TASK_idle=0, U2CD_TASK_WaitFC,//流控 U2CD_TASK_TxCF, U2CD_TASK_WaitResp, U2CD_TASK_NUM }U2CD_TASK_STATE; /******************************************************************************* * the globals ******************************************************************************/ static uint16_t U2CD_pid; static uint16_t U2CD_fid; static uint16_t U2CD_rid; static uint8_t U2CD_stmin; static uint8_t U2CD_fill; static uint8_t U2CD_cfgFlag; static uint8_t U2CD_TTFlag; static uint16_t U2CD_TTLen; static uint8_t U2CD_Txbuf[U2CD_TX_BUF_SIZE]; static uint16_t U2CD_TxCnt;//发送数据指针 static uint8_t U2CD_TxSN; static uint8_t U2CD_TxTimeCounter; static uint8_t U2CD_WaitRespFlag = 0; static uint8_t U2CD_FCFlag = 0; static uint8_t U2CD_Framebuf[8]; static uint8_t U2CD_Rxbuf[U2CD_RX_BUF_SIZE]; static U2CD_TASK_STATE task_state; /******************************************************************************* * the const ******************************************************************************/ /******************************************************************************* * the functions ******************************************************************************/ static void U2CD_TxSF(uint16_t id,uint8_t* data,uint16_t len); static void U2CD_TxFF(uint16_t id,uint8_t* data,uint16_t len); static void U2CD_TxCF(uint16_t id,uint8_t* data,uint16_t len); static void U2CD_TxFC(uint16_t id); void U2CD_Init(void) { U2CD_cfgFlag = 0; U2CD_TTFlag = 0; task_state = U2CD_TASK_idle; } //pid,fid,rid,stmin,fill void U2CD_cfg(uint16_t pid,uint16_t fid,uint16_t rid,uint8_t stmin,uint8_t fill) { if (pid<0x7ff&&fid<0x7ff&&rid<0x7ff) { U2CD_pid = pid; U2CD_fid = fid; U2CD_rid = rid; U2CD_stmin = stmin; U2CD_fill = fill; U2CD_cfgFlag = 1; CanDrv_SetDiagID(pid,rid); printf("ok:config finished\n"); } else { U2CD_cfgFlag = 0; printf("err:配置错误\n"); } } void U2CD_TickTask(void) { U2CD_TxTimeCounter++; } void U2CD_Task(void) { CanDrv_MsgRecvTask(); switch (task_state) { case U2CD_TASK_idle: if (U2CD_TTFlag == 1) { if (U2CD_TTLen <= 7) { //printf("debug:send SF\n"); U2CD_TxSF(U2CD_pid,U2CD_Txbuf,U2CD_TTLen); task_state = U2CD_TASK_WaitResp; U2CD_TxTimeCounter = 0; U2CD_WaitRespFlag = 0; } else { //printf("debug:send FF"); U2CD_TxFF(U2CD_pid,U2CD_Txbuf,U2CD_TTLen); task_state = U2CD_TASK_WaitFC; U2CD_TxTimeCounter = 0; U2CD_FCFlag = 0; } U2CD_TTFlag = 0; U2CD_TTLen = 0; } break; case U2CD_TASK_WaitFC: if (U2CD_TxTimeCounter > N_Bs) { printf("err:N_Bs timeout\n"); task_state = U2CD_TASK_idle; } if (U2CD_FCFlag == 1) { U2CD_FCFlag = 0; U2CD_TxTimeCounter = 0; task_state = U2CD_TASK_TxCF; } break; case U2CD_TASK_TxCF: if (U2CD_TxTimeCounter > U2CD_stmin) { if (CanDrv_GetCANTxEmpty() == 1) { U2CD_TxTimeCounter = 0; if (U2CD_TxCnt+6 < U2CD_TTLen) { U2CD_TxCF(U2CD_pid,&U2CD_Txbuf[U2CD_TxCnt],6); U2CD_TxCnt += 6; } else { //最后一帧 U2CD_TxCF(U2CD_pid,&U2CD_Txbuf[U2CD_TxCnt],(U2CD_TTLen-U2CD_TxCnt)); task_state = U2CD_TASK_WaitResp; } } } if (U2CD_TxTimeCounter>N_As) { printf("err:N_As timeout\n"); task_state = U2CD_TASK_idle; } break; case U2CD_TASK_WaitResp: if (U2CD_TxTimeCounter>P2_SERVER) { printf("err:P2_SERVER timeout\n"); task_state = U2CD_TASK_idle; } if (U2CD_WaitRespFlag == 1) { //printf("ok:get resp\n"); U2CD_WaitRespFlag = 0; task_state = U2CD_TASK_idle; } break; default: break; } } void U2CD_TTreq(uint8_t* data,uint16_t len) { if (len > U2CD_TX_BUF_SIZE) { printf("err:len too long"); return; } if (U2CD_cfgFlag == 0) { printf("err:no cfg"); return; } if (task_state != U2CD_TASK_idle) { printf("err:busy"); return; } memcpy(U2CD_Txbuf,data,len); U2CD_TTLen = len; U2CD_TTFlag = 1; } void U2CD_DiagMsgProReq(uint8_t *data,uint16_t len) { U2CD_WaitRespFlag = 1; //printf("ok:get pdu\n"); printf("data:"); uartapp_TxHexData(data,len); printf("\nend\n"); } void U2CD_PackDiagMsg(uint8_t *data) { //变量大小需要考虑PDU_BUF_SIZE大小 static uint8_t pointer,maxlen,flag_getff,last_frame_sn; uint8_t n_pci = data[0]>>4; switch (n_pci) { case 0://单帧 maxlen = data[0]&0x0f; memcpy(U2CD_Rxbuf,&data[1],maxlen); U2CD_DiagMsgProReq(U2CD_Rxbuf,maxlen); flag_getff = 0; break; case 1://首帧 maxlen = ((data[0]&0x0f)<<8) + data[1]; if (maxlen <= U2CD_RX_BUF_SIZE) { U2CD_TxFC(U2CD_pid); memcpy(U2CD_Rxbuf,&data[2],6); flag_getff = 1; last_frame_sn = 0; pointer = 6; } else { printf("err:data too long\n"); } break; case 2://连续帧 if (flag_getff != 1) { //未收到首帧 printf("err:not get ff\n"); break; } uint8_t frame_sn = data[0]&0x0f; if (((last_frame_sn+1)&0x0f) == frame_sn) {//sn 正确 if (pointer+7 >= maxlen) {//最后一帧 memcpy(&U2CD_Rxbuf[pointer],&data[1],(maxlen-pointer)); U2CD_DiagMsgProReq(U2CD_Rxbuf,maxlen); flag_getff = 0; //printf("debug:lcf\n"); } else { //printf("debug:cf\n"); memcpy(&U2CD_Rxbuf[pointer],&data[1],7); pointer+=7; } last_frame_sn = frame_sn; } else { printf("err:sn err %d\n",frame_sn); } break; case 3: //printf("ok:get FC\n"); U2CD_FCFlag = 1; break; default: break; } } static void U2CD_TxSF(uint16_t id,uint8_t* data,uint16_t len) { U2CD_Framebuf[0] = len; memcpy(&U2CD_Framebuf[1],data,len); if (len < 7) { for (uint8_t i = (len+1); i < 8; i++) { U2CD_Framebuf[i] = U2CD_fill; } } CanDrv_Txmsg(id,U2CD_Framebuf); } static void U2CD_TxFF(uint16_t id,uint8_t* data,uint16_t len) { U2CD_Framebuf[0] = 0x10 + (len>>8); U2CD_Framebuf[1] = len&0xff; memcpy(&U2CD_Framebuf[2],data,6); CanDrv_Txmsg(id,U2CD_Framebuf); U2CD_TxCnt+=6; U2CD_TxSN = 1; } static void U2CD_TxCF(uint16_t id,uint8_t* data,uint16_t len) { U2CD_Framebuf[0] = 0x20 + (U2CD_TxSN&0x0f); memcpy(&U2CD_Framebuf[1],data,len); if (len < 7) { for (uint8_t i = (len+1); i < 8; i++) { U2CD_Framebuf[i] = U2CD_fill; } } CanDrv_Txmsg(id,U2CD_Framebuf); U2CD_TxSN++; } static void U2CD_TxFC(uint16_t id) { U2CD_Framebuf[0] = 0x30; U2CD_Framebuf[1] = 8;//bs U2CD_Framebuf[2] = 0;//stmin for (uint8_t i = 3; i < 8; i++) { U2CD_Framebuf[i] = U2CD_fill; } CanDrv_Txmsg(id,U2CD_Framebuf); }