351 lines
8.6 KiB
C
351 lines
8.6 KiB
C
/*******************************************************************************
|
|
* the includes
|
|
******************************************************************************/
|
|
#include "Uart2CanDiagApp.h"
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#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);
|
|
}
|