#include "ef_a.h" #include "inout.h" #include "delay.h" #include "trigger.h" #ifndef EF_NUM #define EF_NUM 1 #endif EFCommCtrl g_efCommCtrl[EF_NUM]; void EFDefOutEn(void) { } void EFDefOutDis(void) { } void RegisterEFCommFunc(EFCommCtrl* pCtrl, UsartSendData send, UsartGetData get, UsartCleanRsBuf clean, IsUsartSendOver sdover, CommOutFunc outen, CommOutFunc outdis) { pCtrl->EFCommSend = send; pCtrl->EFCommReceive = get; pCtrl->EFCommCleanRsBuf = clean; pCtrl->IsEFCommSendOver = sdover; pCtrl->CommOutEn = outen; pCtrl->CommOutDis = outdis; } void InitEF(int idx, int usart, BAUD_TypeDef baud, char dat, char parity, char stop) { if (idx < 0 || idx >= EF_NUM) { return; } memset(&g_efCommCtrl[idx], 0, sizeof(EFCommCtrl)); // 延时 switch(baud) { // 数据位 + 1个起始位 + 奇偶校验位(无校验则没有) + 停止位 // 根据波特率来计算 通讯延时, 单位us = 10000000 / baud(按照一个字节10位计算, 8 N 1) case B4800: { g_efCommCtrl[idx].efSendWait = 2200; break; } case B9600: { g_efCommCtrl[idx].efSendWait = 1100; break; } case B14400: { g_efCommCtrl[idx].efSendWait = 750; break; } case B19200: { g_efCommCtrl[idx].efSendWait = 600; break; } case B38400: { g_efCommCtrl[idx].efSendWait = 300; break; } case B57600: { g_efCommCtrl[idx].efSendWait = 200; break; } case B115200: { g_efCommCtrl[idx].efSendWait = 100; break; } case B230400: { g_efCommCtrl[idx].efSendWait = 50; break; } case B460800: { g_efCommCtrl[idx].efSendWait = 25; break; } case B921600: { g_efCommCtrl[idx].efSendWait = 13; break; } default: { g_efCommCtrl[idx].efSendWait = 0; } } #ifndef USART1_485OutEn #define USART1_485OutEn EFDefOutEn #endif #ifndef USART1_485OutDis #define USART1_485OutDis EFDefOutDis #endif #ifndef USART2_485OutEn #define USART2_485OutEn EFDefOutEn #endif #ifndef USART2_485OutDis #define USART2_485OutDis EFDefOutDis #endif #ifndef USART3_485OutEn #define USART3_485OutEn EFDefOutEn #endif #ifndef USART3_485OutDis #define USART3_485OutDis EFDefOutDis #endif #ifndef USART4_485OutEn #define USART4_485OutEn EFDefOutEn #endif #ifndef USART4_485OutDis #define USART4_485OutDis EFDefOutDis #endif #ifndef USART5_485OutEn #define USART5_485OutEn EFDefOutEn #endif #ifndef USART5_485OutDis #define USART5_485OutDis EFDefOutDis #endif #ifndef USART6_485OutEn #define USART6_485OutEn EFDefOutEn #endif #ifndef USART6_485OutDis #define USART6_485OutDis EFDefOutDis #endif // 初始化串口 switch(usart) { #ifdef COMM_USART1 case COMM_USART1: { InitUsart1(baud, dat, parity, stop); // 串口1 RegisterEFCommFunc(&g_efCommCtrl[idx], Usart1SendData, Usart1GetData, Usart1CleanRsBuf, IsUsart1SendOver, USART1_485OutEn, USART1_485OutDis); break; } #endif #ifdef COMM_USART2 case COMM_USART2: { InitUsart2(baud, dat, parity, stop); // 串口2 RegisterEFCommFunc(&g_efCommCtrl[idx], Usart2SendData, Usart2GetData, Usart2CleanRsBuf, IsUsart2SendOver, USART2_485OutEn, USART2_485OutDis); break; } #endif #ifdef COMM_USART3 case COMM_USART3: { InitUsart3(baud, dat, parity, stop); // 串口3 RegisterEFCommFunc(&g_efCommCtrl[idx], Usart3SendData, Usart3GetData, Usart3CleanRsBuf, IsUsart3SendOver, USART3_485OutEn, USART3_485OutDis); break; } #endif #ifdef COMM_USART4 case COMM_USART4: { InitUsart4(baud, dat, parity, stop); // 串口4 RegisterEFCommFunc(&g_efCommCtrl[idx], Usart4SendData, Usart4GetData, Usart4CleanRsBuf, IsUsart4SendOver, USART4_485OutEn, USART4_485OutDis); break; } #endif #ifdef COMM_USART5 case COMM_USART5: { InitUsart5(baud, dat, parity, stop); // 串口5 RegisterEFCommFunc(&g_efCommCtrl[idx], Usart5SendData, Usart5GetData, Usart5CleanRsBuf, IsUsart5SendOver, USART5_485OutEn, USART5_485OutDis); break; } #endif #ifdef COMM_USART6 case COMM_USART6: { InitUsart6(baud, dat, parity, stop); // 串口6 RegisterEFCommFunc(&g_efCommCtrl[idx], Usart6SendData, Usart6GetData, Usart6CleanRsBuf, IsUsart6SendOver, USART6_485OutEn, USART6_485OutDis); break; } #endif default: { break; } } g_efCommCtrl[idx].CommOutDis(); // 关闭发送 } int EFTx(int idx, u8 addr, u16 data, int steps) { int i, timeout, result; u8 pSDat[3]; if ( ((addr & 0xF0) != 0xE0) && ((addr & 0xF0) != 0xF0) ) { return -1; } if (steps == 1 || steps == -1) { g_efCommCtrl[idx].CommOutEn(); // 打开发送 if (steps == -1) { DelayUs(100); } } if (steps == 2 || steps == -1) { i = 0; result = 0; pSDat[i++] = addr; if ((addr & 0xF0) == 0xF0) { pSDat[i++] = HIBYTE(data); pSDat[i++] = LOBYTE(data); } else { pSDat[i++] = data; } g_efCommCtrl[idx].EFCommSend(pSDat, i); } if (steps == 3) { if (g_efCommCtrl[idx].IsEFCommSendOver() != TRUE) { return 0; } } else if (steps == -1) // 同步发送 { timeout = (i*2 + 4) * g_efCommCtrl[idx].efSendWait; // 超时时间,单位us((字节数*2 + 4) * 每个字节发送时长) do //等待发送完成 { if (g_efCommCtrl[idx].IsEFCommSendOver() == TRUE) { break; } DelayUs(1); if (timeout-- <= 0) { result = -2; break; } }while(1); DelayUs(g_efCommCtrl[idx].efSendWait); // 等待最后一个字节发送完成 } if (steps == 4 || steps == -1) { g_efCommCtrl[idx].EFCommCleanRsBuf(); // 清空已接收的数据 g_efCommCtrl[idx].CommOutDis(); // 关闭发送 } if (steps != -1) { return steps; } return result; } int EFRx(int idx, u16 * pData, int steps) { int exlen, timeout, result; u8 pRDat[3]; if (pData == NULL || (steps != 1 && steps != -1)) { return -1; } memset(pRDat, 0, 3); exlen = 3; timeout = exlen*2 + 200; // 超时时间 do { result = g_efCommCtrl[idx].EFCommReceive(pRDat, exlen); // 从缓冲区读取数据 if (result >= exlen) { // 处理数据包 if (pRDat[0] != 0xE0) { result = -4; // 接收错误 break; } *pData = MAKEWORD(pRDat[2], pRDat[1]); break; } else if (result < 0) { if (result == -2) // 串口没有初始化 { printf("usart is not inited\r\n"); } else if (result == -3) // 接收缓冲区控制错误 { printf("usart receive buf ctrl error\r\n"); } break; } if (steps == -1) { // 等待接收完成 DelayUs(g_efCommCtrl[idx].efSendWait); if (timeout-- <= 0) { printf("2. call EFRx timeout\r\n"); result = -5; //接收超时 break; } } else { result = 0; break; } }while(1); return result; } int EFComm(int idx, u8 addr, u16 wrDat, u16 * pRdBuf) { int result; result = EFTx(idx, addr, wrDat, -1); if (result == 0) { // 等待回包 if (addr == 0xE0 && wrDat >= 32 && wrDat <= 63) { if (pRdBuf != NULL) { result = EFRx(idx, pRdBuf, -1); } } } return result; } AsyncEFCtrl g_asyncefCtrl[EF_NUM]; void InitAsyncEFCtrl(int idx, int rsvtimout) { memset(&g_asyncefCtrl[idx], 0, sizeof(AsyncEFCtrl)); // 读取超时时间 if (rsvtimout < 20) { g_asyncefCtrl[idx].efrsvTimout = 20; } else if (rsvtimout > 200) { g_asyncefCtrl[idx].efrsvTimout = 200; } else { g_asyncefCtrl[idx].efrsvTimout = rsvtimout; } } void RegEFCmdProc(int idx, ResvEFProc proc) { g_asyncefCtrl[idx].resvefproc = proc; } int AddEFCmd(EFCmd * pCmd) { if (pCmd != NULL) { AsyncEFCtrl * p485Ctrl = &g_asyncefCtrl[pCmd->idx]; if (p485Ctrl != NULL) { if (p485Ctrl->bufCmdNum < MAX_EF_CMD && p485Ctrl->bufTail < MAX_EF_CMD) { memcpy(&(p485Ctrl->cmdbuf[p485Ctrl->bufTail]), pCmd, sizeof(EFCmd)); p485Ctrl->bufTail++; if (p485Ctrl->bufTail >= MAX_EF_CMD) { p485Ctrl->bufTail = 0; } p485Ctrl->bufCmdNum++; return p485Ctrl->bufCmdNum; } else { printf("ef %d cmd buff full\r\n", pCmd->idx); return -2; } } return -1; } return -1; } int GetEFCmdBufLen(int idx) { return g_asyncefCtrl[idx].bufCmdNum; } int AsyncEFTask(int idx) { // 分步骤执行 int rslt; u32 curIime; EFCmd *pCmd; AsyncEFCtrl * p485Ctrl = &g_asyncefCtrl[idx]; if (p485Ctrl == NULL) { return -1; } pCmd = &(p485Ctrl->cmdbuf[p485Ctrl->bufHead]); // 读取当前时间 curIime = GetUsSoftTimer(); if ((curIime - p485Ctrl->stepTime) > g_efCommCtrl[pCmd->idx].efSendWait) { p485Ctrl->stepTime = curIime; if (p485Ctrl->working == 0 && p485Ctrl->bufCmdNum > 0 && p485Ctrl->steps == 0) { p485Ctrl->working = 1; p485Ctrl->steps = 1; } if (p485Ctrl->working == 0) { p485Ctrl->steps = 0; return 0; } if (p485Ctrl->steps > 0 && p485Ctrl->steps < 5) { rslt = EFTx(pCmd->idx, pCmd->addr, pCmd->wrdat, p485Ctrl->steps); if (rslt == p485Ctrl->steps) { p485Ctrl->steps++; } } else if (p485Ctrl->steps >= 5 && p485Ctrl->steps < p485Ctrl->efrsvTimout) { // 等待回包 if (pCmd->addr == 0xE0 && pCmd->wrdat >= 32 && pCmd->wrdat <= 63) { rslt = EFRx(pCmd->idx, &pCmd->rddat, 1); if (rslt == 3) // 读到正确数据 { // 执行读到数据函数 if (p485Ctrl->resvefproc != NULL) { p485Ctrl->resvefproc(pCmd); } p485Ctrl->steps = p485Ctrl->efrsvTimout; } else { p485Ctrl->steps++; } } else { p485Ctrl->steps = p485Ctrl->efrsvTimout; } } else { p485Ctrl->steps++; } if (p485Ctrl->steps >= p485Ctrl->efrsvTimout) { if (p485Ctrl->bufCmdNum > 0) { p485Ctrl->bufCmdNum--; } p485Ctrl->steps = 0; p485Ctrl->working = 0; p485Ctrl->bufHead++; if (p485Ctrl->bufHead >= MAX_EF_CMD) { p485Ctrl->bufHead = 0; } } } return p485Ctrl->steps; }