#define _IN_EMBFPGA_C #include "embfpga.h" //---------------------------------------------------------------------------- #include "corefmc.h" #include "inout.h" #include "shell.h" //---------------------------------------------------------------------------- void TestFPGA(char * para1, char * para2); //---------------------------------------------------------------------------- // 初始化FPGA void InitEmbFpga(void) { int hardver = GetFpgaHardVersion(); printf("\r\nFPGA Hard Version = Ver %x.%x \r\n", (hardver&0xff00)>>8,(hardver&0x00ff)); int softver = GetFpgaSoftVersion(); printf("\r\nFPGA Soft Version = Ver %x.%x \r\n", (softver&0xff00)>>8,(softver&0x00ff)); SetExoutEnOn(); // 输出允许 //AddShellCmd("FPGA", "test rw fpga", TestFPGA); } //---------------------------------------------------------------------------- // 读端口 // 读取硬件版本 u16 GetFpgaHardVersion(void) { static u16 hardver = 0; if ((hardver == 0) || (hardver == 0xffff)) {// 上电后只从FPGA中读一次 hardver = FmcReadReg(FPGA_HARD_VERSION); } return hardver; } // 读取软件版本 u16 GetFpgaSoftVersion(void) { static u16 softver = 0; if ((softver == 0) || (softver == 0xffff)) {// 上电后只从FPGA中读一次 softver = FmcReadReg(FPGA_SOFT_VERSION); } return softver; } // 得到虚轴运行状态 u16 GetRunStatus(void) { SetVAxisConfig(VCTR_LOCK); // 锁存 return FmcReadReg(VAXIS_STATUS); } // 得到虚轴表状态 u16 GetRunStatus1(void) { return FmcReadReg(VAXIS_STATUS1); } // 得到输入端口中断信息 u16 GetInputIntFlags(void) { return (FmcReadReg(INPUT_INT_FLAGS) & INPUT_INT_MASK); } // 得到编码器中断信息 u16 GetEcdIntFlags(void) { return (FmcReadReg(ECD_INT_FLAGS) & ECD_INT_MASK); } // 读取虚轴1的运行频率 u32 GetVAxis1PPS(void) { u32 freq; SetVAxisConfig(VCTR_LOCK); // 锁存 freq = FmcReadReg(CUR_VAXIS1_PPS_H); // 高字 freq <<= 16; freq += FmcReadReg(CUR_VAXIS1_PPS_L); // 低字 return freq; } // 读取虚轴的运行频率 // vaxisId: VAXIS_ID1 u32 GetVAxisPPS(u16 vaxisId) { assert_param(IS_VAXIS_ID(vaxisId)); switch (vaxisId) { case VAXIS_ID1: return GetVAxis1PPS(); default: return 0; } } // 读取上一个表结束时的虚轴频率 u32 GetLastVAxisFrequency(u16 vaxisId) { u32 freq; assert_param(vaxisId == VAXIS_ID1); if (vaxisId == VAXIS_ID1) { freq = FmcReadReg(VAXIS1_END_FREQUENCY_H); // 高字 freq <<= 16; freq += FmcReadReg(VAXIS1_END_FREQUENCY_L); // 低字 } else { freq = 0; } return freq; } // 读取虚轴1的计数值 u32 GetVAxis1Counter(void) { u32 Counter; SetVAxisConfig(VCTR_LOCK); // 锁存 Counter = FmcReadReg(CUR_VAXIS1_COUNTER_H); // 高字 Counter <<= 16; Counter += FmcReadReg(CUR_VAXIS1_COUNTER_L); // 低字 return Counter; } // 读取虚轴的计数值 // vaxisId: VAXIS_ID1 u32 GetVAxisCounter(u16 vaxisId) { assert_param(IS_VAXIS_ID(vaxisId)); switch (vaxisId) { case VAXIS_ID1: return GetVAxis1Counter(); default: return 0; } } // 读取实轴1计数器值 s32 GetAxis1Counter(void) { s32 Counter; SetVAxisConfig(VCTR_LOCK); // 锁存 Counter = FmcReadReg(CUR_AXIS1_COUNTER_H); // 高字 Counter <<= 16; Counter += FmcReadReg(CUR_AXIS1_COUNTER_L); // 低字 return Counter; } // 读取实轴2计数器值 s32 GetAxis2Counter(void) { s32 Counter; SetVAxisConfig(VCTR_LOCK); // 锁存 Counter = FmcReadReg(CUR_AXIS2_COUNTER_H); // 高字 Counter <<= 16; Counter += FmcReadReg(CUR_AXIS2_COUNTER_L); // 低字 return Counter; } // 读取实轴3计数器值 s32 GetAxis3Counter(void) { s32 Counter; SetVAxisConfig(VCTR_LOCK); // 锁存 Counter = FmcReadReg(CUR_AXIS3_COUNTER_H); // 高字 Counter <<= 16; Counter += FmcReadReg(CUR_AXIS3_COUNTER_L); // 低字 return Counter; } // 读取实轴4计数器值 s32 GetAxis4Counter(void) { s32 Counter; SetVAxisConfig(VCTR_LOCK); // 锁存 Counter = FmcReadReg(CUR_AXIS4_COUNTER_H); // 高字 Counter <<= 16; Counter += FmcReadReg(CUR_AXIS4_COUNTER_L); // 低字 return Counter; } // 读取实轴5计数器值 s32 GetAxis5Counter(void) { s32 Counter; SetVAxisConfig(VCTR_LOCK); // 锁存 Counter = FmcReadReg(CUR_AXIS5_COUNTER_H); // 高字 Counter <<= 16; Counter += FmcReadReg(CUR_AXIS5_COUNTER_L); // 低字 return Counter; } // 读取实轴6计数器值 s32 GetAxis6Counter(void) { s32 Counter; SetVAxisConfig(VCTR_LOCK); // 锁存 Counter = FmcReadReg(CUR_AXIS6_COUNTER_H); // 高字 Counter <<= 16; Counter += FmcReadReg(CUR_AXIS6_COUNTER_L); // 低字 return Counter; } // 读取实轴计数器值 // axisId: AXIS_ID1 ~ AXIS_ID6 s32 GetAxisCounter(u16 axisId) { assert_param(IS_AXIS_ID(axisId)); switch (axisId) { case AXIS_ID1: return GetAxis1Counter(); case AXIS_ID2: return GetAxis2Counter(); case AXIS_ID3: return GetAxis3Counter(); case AXIS_ID4: return GetAxis4Counter(); case AXIS_ID5: return GetAxis5Counter(); case AXIS_ID6: return GetAxis6Counter(); default: return -1; } } // 得到编码器1的数值 s32 GetEcd1Value(void) { s32 Counter; SetVAxisConfig(VCTR_LOCK); // 锁存 Counter = FmcReadReg(CUR_ECD1_COUNTER_H); // 高字 Counter <<= 16; Counter += FmcReadReg(CUR_ECD1_COUNTER_L); // 低字 return Counter; } // 得到编码器2的数值 s32 GetEcd2Value(void) { s32 Counter; SetVAxisConfig(VCTR_LOCK); // 锁存 Counter = FmcReadReg(CUR_ECD2_COUNTER_H); // 高字 Counter <<= 16; Counter += FmcReadReg(CUR_ECD2_COUNTER_L); // 低字 return Counter; } // 得到编码器的数值 // ecdId: ECD_SEL1 ~ ECD_SEL2 s32 GetEcdCounter(u16 ecdId) { assert_param(IS_ECD_SEL(ecdId)); switch (ecdId) { case ECD_SEL1: return GetEcd1Value(); case ECD_SEL2: return GetEcd2Value(); default: return -1; } } // 读取OP计数器值 u32 GetOPCounter(void) { u32 Counter; SetVAxisConfig(VCTR_LOCK); // 锁存 Counter = FmcReadReg(CUR_OP_COUNTER_H); // 高字 Counter <<= 16; Counter += FmcReadReg(CUR_OP_COUNTER_L); // 低字 return Counter; } // 读取ZP计数器值 u32 GetZPCounter(void) { u32 Counter; SetVAxisConfig(VCTR_LOCK); // 锁存 Counter = FmcReadReg(CUR_ZP_COUNTER_H); // 高字 Counter <<= 16; Counter += FmcReadReg(CUR_ZP_COUNTER_L); // 低字 return Counter; } // 得到实轴报警信息 u16 GetAlarmValue(void) { return (FmcReadReg(AXIS_ALM_STATUS) & AXIS_ALM_MASK); } // 得到编码器信号状态 u16 GetEcdStatus(void) { return (FmcReadReg(ECD_SIGNAL_STATUS) & ECD_STA_MASK); } // 得到输入信号状态 u16 GetInputStatus(void) { return (FmcReadReg(INPUT_STATUS)); } //---------------------------------------------------------------------------- // 写端口 // 设置虚轴配置 void SetVAxisConfig(u16 cfg) { assert_param(IS_VAXIS_CMD(cfg)); FmcWriteReg(VAXIS_CONTROL, cfg); } // 功能: 清除FPGA中断 void CleanAllIntFlag(void) { SetVAxisConfig(VCTR_INPUT_ALM_INT); // 清除input中断标志 SetVAxisConfig(VCTR_ZP1_INT); // 编码器1:清除ZP1中断标志 SetVAxisConfig(VCTR_ZP2_INT); // 编码器2:清除ZP1中断标志 SetVAxisConfig(VCTR_VAXIS1_CLEAN_OV1); // 虚轴1清除表1完成中断标志 SetVAxisConfig(VCTR_VAXIS1_CLEAN_OV2); // 虚轴1清除表2完成中断标志 } // 启动虚轴运动 int StartVAxisRun(VAxisCmdStr * pCmd) { u32 addr; if (pCmd == NULL) { return -1; } assert_param(IS_VAXIS_ID(pCmd->vaxisId)); assert_param(IS_BUF_SEL(pCmd->bufSel)); if (pCmd->vaxisId == VAXIS_ID1) // 虚轴1 { if (pCmd->bufSel == BUF_SEL1) { SetVAxisConfig(VCTR_VAXIS1_DIS_BUF1); addr = VAXIS1_BUF1_PARA; } else if (pCmd->bufSel == BUF_SEL2) { SetVAxisConfig(VCTR_VAXIS1_DIS_BUF2); addr = VAXIS1_BUF2_PARA; } else if (pCmd->bufSel == BUF_SEL3) { SetVAxisConfig(VCTR_VAXIS1_DIS_BUF3); addr = VAXIS1_BUF3_PARA; } else { return -1; } } else { return -1; } if ((pCmd->vaxisId == VAXIS_ID1) || // 虚轴1 0 ) { if (pCmd->calcGap > MAX_GAP) { // printf("calcGap=%d > MAX_GAP\r\n", pCmd->calcGap); pCmd->calcGap = MAX_GAP; } else if (pCmd->calcGap < MIN_GAP) { // printf("calcGap=%d < MIN_GAP\r\n", pCmd->calcGap); pCmd->calcGap = MIN_GAP; } if (pCmd->startPPS > MAX_PPS) { printf("startPPS=%d > MAX_PPS\r\n", pCmd->startPPS); pCmd->startPPS = MAX_PPS; } else if (pCmd->startPPS < MIN_PPS) { printf("startPPS=%d < MIN_PPS\r\n", pCmd->startPPS); pCmd->startPPS = MIN_PPS; return -1; // 修改防止运动太慢,认为死机 } if (pCmd->runPPS > MAX_PPS) { printf("runPPS=%d > MAX_PPS\r\n", pCmd->runPPS); pCmd->runPPS = MAX_PPS; } else if (pCmd->runPPS < MIN_PPS) { printf("runPPS=%d < MIN_PPS\r\n", pCmd->runPPS); pCmd->runPPS = MIN_PPS; return -1; // 修改防止运动太慢,认为死机 } FmcWriteReg(addr, LOWORD(pCmd->calcGap)); FmcWriteReg(addr, HIWORD(pCmd->calcGap)); // 计算时间间隔,1/72 us 为单位 FmcWriteReg(addr, LOWORD(pCmd->startPPS)); FmcWriteReg(addr, HIWORD(pCmd->startPPS)); // 启动频率,单位pps FmcWriteReg(addr, LOWORD(pCmd->runPPS)); FmcWriteReg(addr, HIWORD(pCmd->runPPS)); // 目标频率,单位pps if (pCmd->bufSel != BUF_SEL3) { assert_param(pCmd->outNum <= MAX_OUTNUM); assert_param(pCmd->outNum >= MIN_OUTNUM); assert_param(pCmd->jumpNum <= MAX_OUTNUM); FmcWriteReg(addr, LOWORD(pCmd->outNum)); FmcWriteReg(addr, HIWORD(pCmd->outNum)); // 本次输出虚轴脉冲个数,单位个 FmcWriteReg(addr, LOWORD(pCmd->jumpNum)); FmcWriteReg(addr, HIWORD(pCmd->jumpNum)); // 变速跳过虚轴脉冲个数 FmcWriteReg(addr, VOK_FLAG); // OK } else { FmcWriteReg(addr, VOK_FLAG); } // 虚轴运行 if (pCmd->vaxisId == VAXIS_ID1) { // printf("vaxis 1 run cmd\r\n"); SetVAxisConfig(VCTR_VAXIS1_RUN); } else { } } else { return -1; } return 0; } // 虚轴:停止当前运动 int StopVAxisRun(u16 vaxisId) { assert_param(IS_VAXIS_ID(vaxisId)); //虚轴停止 if (vaxisId == VAXIS_ID1 || vaxisId == VAXIS_ID_ALL) { SetVAxisConfig(VCTR_VAXIS1_STOP); SetVAxisConfig(VCTR_VAXIS1_CLEAN_OV1); SetVAxisConfig(VCTR_VAXIS1_CLEAN_OV2); SetVAxisConfig(VCTR_VAXIS1_DIS_BUF1); SetVAxisConfig(VCTR_VAXIS1_DIS_BUF2); SetVAxisConfig(VCTR_VAXIS1_DIS_BUF3); } return 0; } // 虚轴:速度解除速度临时控制 void StopSpdCtrl(u16 vaxisId) { assert_param(IS_VAXIS_ID(vaxisId)); if (vaxisId == VAXIS_ID1 || vaxisId == VAXIS_ID_ALL) { SetVAxisConfig(VCTR_VAXIS1_DIS_BUF3); } } // 编码器的数值清零 // ecdId: ECD_SEL1 ~ ECD_SEL2 void ClearEcdCounter(u16 ecdId) { assert_param(IS_ECD_SEL(ecdId)); switch (ecdId) { case ECD_SEL1: SetVAxisConfig(VCTR_ECD1_CLEAR); break; case ECD_SEL2: SetVAxisConfig(VCTR_ECD2_CLEAR); break; default: break; } } void ReetEcdABZLevel(u16 ecdId) { switch (ecdId) { case ECD_SEL1: SetVAxisConfig(VCTR_ECD1_LEVEL_RST); break; case ECD_SEL2: SetVAxisConfig(VCTR_ECD1_LEVEL_RST); break; default: break; } } void SetEcdAPLevelNegative(u16 ecdId) { switch (ecdId) { case ECD_SEL1: SetVAxisConfig(VCTR_AP1_LEVEL_NEG); break; case ECD_SEL2: SetVAxisConfig(VCTR_AP2_LEVEL_NEG); break; default: break; } } void SetEcdAZLevelNegative(u16 ecdId) { switch (ecdId) { case ECD_SEL1: SetVAxisConfig(VCTR_AZ1_LEVEL_NEG); break; case ECD_SEL2: SetVAxisConfig(VCTR_AZ2_LEVEL_NEG); break; default: break; } } void SetEcdZPLevelNegative(u16 ecdId) { switch (ecdId) { case ECD_SEL1: SetVAxisConfig(VCTR_ZP1_LEVEL_NEG); break; case ECD_SEL2: SetVAxisConfig(VCTR_ZP2_LEVEL_NEG); break; default: break; } } // OP输出 void SetOpOutOn(void) { SetVAxisConfig(VCTR_OPOS_ON); } void SetOpOutOff(void) { SetVAxisConfig(VCTR_OPOS_NONE); } void SetZpOutOn(void) { SetVAxisConfig(VCTR_ZPOS_ON); } void SetZpOutOff(void) { SetVAxisConfig(VCTR_ZPOS_NONE); } // 设置报警命令 void SetAxisAlarmConfig(u16 axisId, u16 alm) { assert_param(IS_AXIS_ID(axisId)); SetVAxisConfig(MAKE_VCTR_AXIS_ALM_CMD(axisId,alm)); } //-------------------------------------------------------------------------------------------------------------- // 设置OP输出的分频系数 void SetOpDivision(u16 div) { if (div != OP_OUT_DIRECT) { div &= 0xFFFE; } FmcWriteReg(OP_OUT_DIVISION, div); } // 设置OP计数值 void SetOpCounter(s32 cnt) { FmcWriteReg(OP_COUNTER_SET_L, LOWORD(cnt)); FmcWriteReg(OP_COUNTER_SET_H, HIWORD(cnt)); } // 设置ZP计数值 void SetZpCounter(s32 cnt) { FmcWriteReg(ZP_COUNTER_SET_L, LOWORD(cnt)); FmcWriteReg(ZP_COUNTER_SET_H, HIWORD(cnt)); } void SetEcd1Counter(s32 cnt) { FmcWriteReg(ECD1_COUNTER_SET_L, LOWORD(cnt)); FmcWriteReg(ECD1_COUNTER_SET_H, HIWORD(cnt)); } void SetEcd2Counter(s32 cnt) { FmcWriteReg(ECD2_COUNTER_SET_L, LOWORD(cnt)); FmcWriteReg(ECD2_COUNTER_SET_H, HIWORD(cnt)); } // 设置编码器计数值 void SetEcdCounter(u16 ecdId, s32 cnt) { assert_param(IS_ECD_SEL(ecdId)); switch(ecdId) { case ECD_SEL1: { SetEcd1Counter(cnt); break; } case ECD_SEL2: { SetEcd2Counter(cnt); break; } default: break; } } // 设置输入端口中断配置 void SetInputInt(u16 cfg) { FmcWriteReg(INPUT_INT_SET, cfg); } #define MAX_OUTPUT_NUM 8 u16 g_outputValue = 0; void Output1On(void) { g_outputValue |= OUTPUT1_BIT; FmcWriteReg(OUTPUT_SET, g_outputValue); } void Output1Off(void) { g_outputValue &= (~OUTPUT1_BIT); FmcWriteReg(OUTPUT_SET, g_outputValue); } void Output2On(void) { g_outputValue |= OUTPUT2_BIT; FmcWriteReg(OUTPUT_SET, g_outputValue); } void Output2Off(void) { g_outputValue &= (~OUTPUT2_BIT); FmcWriteReg(OUTPUT_SET, g_outputValue); } void Output3On(void) { g_outputValue |= OUTPUT3_BIT; FmcWriteReg(OUTPUT_SET, g_outputValue); } void Output3Off(void) { g_outputValue &= (~OUTPUT3_BIT); FmcWriteReg(OUTPUT_SET, g_outputValue); } void Output4On(void) { g_outputValue |= OUTPUT4_BIT; FmcWriteReg(OUTPUT_SET, g_outputValue); } void Output4Off(void) { g_outputValue &= (~OUTPUT4_BIT); FmcWriteReg(OUTPUT_SET, g_outputValue); } void Output5On(void) { g_outputValue |= OUTPUT5_BIT; FmcWriteReg(OUTPUT_SET, g_outputValue); } void Output5Off(void) { g_outputValue &= (~OUTPUT5_BIT); FmcWriteReg(OUTPUT_SET, g_outputValue); } void Output6On(void) { g_outputValue |= OUTPUT6_BIT; FmcWriteReg(OUTPUT_SET, g_outputValue); } void Output6Off(void) { g_outputValue &= (~OUTPUT6_BIT); FmcWriteReg(OUTPUT_SET, g_outputValue); } void Output7On(void) { g_outputValue |= OUTPUT7_BIT; FmcWriteReg(OUTPUT_SET, g_outputValue); } void Output7Off(void) { g_outputValue &= (~OUTPUT7_BIT); FmcWriteReg(OUTPUT_SET, g_outputValue); } void Output8On(void) { g_outputValue |= OUTPUT8_BIT; FmcWriteReg(OUTPUT_SET, g_outputValue); } void Output8Off(void) { g_outputValue &= (~OUTPUT8_BIT); FmcWriteReg(OUTPUT_SET, g_outputValue); } // 得到某个输出口状态 u8 GetOutputVal(int num) { if (num > 0 && num <= MAX_OUTPUT_NUM) { u16 mod = 0x01; mod <<= (num-1); if ((g_outputValue & mod) != 0) { return SENSOR_ON; } else { return SENSOR_OFF; } } return SENSOR_OFF; } //------------------------------------------------------------- // 设置实轴输出配置 void SetAxisConfig(u16 axisId, u16 cfg) { assert_param(IS_AXIS_ID(axisId)); assert_param(IS_AXIS_CMD(cfg)); FmcWriteReg(AXIS_CONFIG(AXIS(axisId)), cfg); } u32 GetSineNums(u16 sineout, u16* pBuffer, u32 num) { u32 sinenum, temp; sinenum = 0; if (sineout != 0) { while(num != 0) { temp = (*pBuffer) & 0x7fff; sinenum += temp; //temp = (u32)(temp * SINE_MUTI + 0.5); temp = (u32)(temp * SINE_MUTI + 0.999f); // 20220407 ljs 李帅 王春刚 修改,修复在走少量脉冲时丢脉冲的现象 if (temp > 0x7fff) { printf("sine calc error\r\n"); sinenum += 0x100000; // 返回大于 0xfffff 的数,以便在调用函数中报错 } *pBuffer &= 0x8000; *pBuffer |= (temp & 0x7fff); num--; pBuffer++; } } return sinenum; } // 写插补数据 // 返回值: 0:正常 // -1,输入参数错误 // -2,保留,不允许使用 // -3,fpga 读写错误 // -4,FPGA 版本错误 int WriteInterData(InterData * pCmd) { u32 sineNum; if (pCmd == NULL) { printf("para is empty in WriteInterData\r\n"); return -1; } assert_param(IS_VAXIS_ID(pCmd->vaxisId)); assert_param(IS_AXIS_ID(pCmd->axisId)); assert_param(IS_BUF_SEL(pCmd->bufSel)); assert_param(pCmd->datBufLen < MAX_SEGMENT_PER_BUF); assert_param(pCmd->datBufLen > 0); assert_param(pCmd->startEscNum <= MAX_OUTNUM); assert_param(pCmd->partVxNum <= MAX_OUTNUM); assert_param(pCmd->partVxNum >= MIN_OUTNUM); // 选择虚轴 switch (pCmd->vaxisId) { case VAXIS_ID1: SetAxisConfig((pCmd->axisId), POUT_ENABLE_VAXIS1); // 脉冲输出允许:输入时钟为虚轴1 break; case VAXIS_ECD: SetAxisConfig((pCmd->axisId), POUT_ENABLE_ECD); // 脉冲输出允许:输入为编码器接口 break; default: SetAxisConfig((pCmd->axisId), POUT_DISABLE); // 脉冲输出禁止√ break; } sineNum = GetSineNums(pCmd->sineOut, pCmd->datBuff, pCmd->datBufLen); // 配置实轴参数 if (pCmd->bufSel == BUF_SEL1) { // printf("\r\nwrite buff 1\r\n"); SetAxisConfig((pCmd->axisId), DIS_INTER_BUF1); // 清空表 // 正弦输出模式 FmcWriteReg(AXIS_BUF1_SINE_OUT(AXIS(pCmd->axisId)), (u16)(sineNum & 0xffff)); // 写入正弦数据低位 FmcWriteReg(AXIS_BUF1_SINE_OUT_H(AXIS(pCmd->axisId)), (u16)(sineNum>>16)); // 写入正弦数据高位 FmcWriteConstBuf(INTER_BUF1_DATA(AXIS(pCmd->axisId)), pCmd->datBuff, pCmd->datBufLen); // 写入数据 FmcWriteReg(INTER_BUF1_PARA(AXIS(pCmd->axisId)), LOWORD(pCmd->startEscNum)); // 起始跳过实轴脉冲数 FmcWriteReg(INTER_BUF1_PARA(AXIS(pCmd->axisId)), HIWORD(pCmd->startEscNum)); FmcWriteReg(INTER_BUF1_PARA(AXIS(pCmd->axisId)), LOWORD(pCmd->partVxNum)); // 每段对应虚轴脉冲数 FmcWriteReg(INTER_BUF1_PARA(AXIS(pCmd->axisId)), HIWORD(pCmd->partVxNum)); FmcWriteReg(INTER_BUF1_PARA(AXIS(pCmd->axisId)), LOWORD(pCmd->dirAttr)); // 实轴脉冲输出方向 FmcWriteReg(INTER_BUF1_PARA(AXIS(pCmd->axisId)), HIWORD(pCmd->dirAttr)); FmcWriteReg(INTER_BUF1_PARA(AXIS(pCmd->axisId)), VOK_FLAG); } else if (pCmd->bufSel == BUF_SEL2) { // printf("\r\nwrite buff 2\r\n"); SetAxisConfig((pCmd->axisId), DIS_INTER_BUF2); // 清空表 // 正弦输出模式 FmcWriteReg(AXIS_BUF2_SINE_OUT(AXIS(pCmd->axisId)), (u16)(sineNum & 0xffff)); // 写入正弦数据低位 FmcWriteReg(AXIS_BUF2_SINE_OUT_H(AXIS(pCmd->axisId)), (u16)(sineNum>>16)); // 写入正弦数据高位 FmcWriteConstBuf(INTER_BUF2_DATA(AXIS(pCmd->axisId)), pCmd->datBuff, pCmd->datBufLen); // 写入数据 FmcWriteReg(INTER_BUF2_PARA(AXIS(pCmd->axisId)), LOWORD(pCmd->startEscNum)); // 起始脉冲数 FmcWriteReg(INTER_BUF2_PARA(AXIS(pCmd->axisId)), HIWORD(pCmd->startEscNum)); FmcWriteReg(INTER_BUF2_PARA(AXIS(pCmd->axisId)), LOWORD(pCmd->partVxNum)); // 每段脉冲数 FmcWriteReg(INTER_BUF2_PARA(AXIS(pCmd->axisId)), HIWORD(pCmd->partVxNum)); FmcWriteReg(INTER_BUF2_PARA(AXIS(pCmd->axisId)), LOWORD(pCmd->dirAttr)); // 方向属性 FmcWriteReg(INTER_BUF2_PARA(AXIS(pCmd->axisId)), HIWORD(pCmd->dirAttr)); FmcWriteReg(INTER_BUF2_PARA(AXIS(pCmd->axisId)), VOK_FLAG); } else { printf("bufSel = %d, error\r\n", pCmd->bufSel); return -1; } return 0; } void CleanAxisBuff(u16 axisId, u16 bufSel) { assert_param(IS_AXIS_ID(axisId)); assert_param(IS_BUF_SEL(bufSel)); if (bufSel == BUF_SEL1) { // printf("clean axis %d buff 1\r\n", axisId); SetAxisConfig(axisId, DIS_INTER_BUF1); // 清空表 FmcWriteConstBuf(INTER_BUF1_DATA(AXIS(axisId)), NULL, 0); // 写入空数据 } else if (bufSel == BUF_SEL2) { // printf("clean axis %d buff 2\r\n", axisId); SetAxisConfig(axisId, DIS_INTER_BUF2); // 清空表 FmcWriteConstBuf(INTER_BUF2_DATA(AXIS(axisId)), NULL, 0); // 写入空数据 } } // 设置实轴计数器初值 void SetAxisCounter(u16 axisId, s32 cnt) { assert_param(IS_AXIS_ID(axisId)); FmcWriteReg(AXIS_COUNTER_L(AXIS(axisId)), LOWORD(cnt)); FmcWriteReg(AXIS_COUNTER_H(AXIS(axisId)), HIWORD(cnt)); } // 设置轴PWM分频系数 void SetAxisPwmFreq(u16 axisId, u16 freq) { assert_param(IS_AXIS_PWM_ID(axisId)); assert_param(IS_AXIS_PWM_FREQ(freq)); FmcWriteReg(AXIS_PWM_FREQ(AXIS(axisId)), freq); } // 设置轴PULSE的PWM值 void SetAxisPulsePwm(u16 axisId, u16 val) { if (val > FPGA_PWM_MAX_VAL) { val = FPGA_PWM_MAX_VAL; } assert_param(IS_AXIS_PWM_ID(axisId)); assert_param(IS_AXIS_PWM_VAL(val)); FmcWriteReg(AXIS_PULSE_PWM(AXIS(axisId)), val); } // 设置轴SIGN的PWM值 void SetAxisSignPwm(u16 axisId, u16 val) { if (val > FPGA_PWM_MAX_VAL) { val = FPGA_PWM_MAX_VAL; } assert_param(IS_AXIS_PWM_ID(axisId)); assert_param(IS_AXIS_PWM_VAL(val)); FmcWriteReg(AXIS_SIGN_PWM(AXIS(axisId)), val); } //-------------------------------------------------------------------- typedef void (*InputIntProc)(void); InputIntProc g_inputIntProcAry[16] = {NULL}; void RegInputIntProc(u16 intcfg, void(*inputProc)(void)) { static u16 intconfig = 0; if (intcfg == INPUT1_INT_EN) { g_inputIntProcAry[0] = inputProc; } else if (intcfg == INPUT2_INT_EN) { g_inputIntProcAry[1] = inputProc; } else if (intcfg == INPUT3_INT_EN) { g_inputIntProcAry[2] = inputProc; } else if (intcfg == INPUT4_INT_EN) { g_inputIntProcAry[3] = inputProc; } else if (intcfg == INPUT5_INT_EN) { g_inputIntProcAry[4] = inputProc; } else if (intcfg == INPUT6_INT_EN) { g_inputIntProcAry[5] = inputProc; } else if (intcfg == INPUT7_INT_EN) { g_inputIntProcAry[6] = inputProc; } else if (intcfg == INPUT8_INT_EN) { g_inputIntProcAry[7] = inputProc; } else if (intcfg == INPUT9_INT_EN) { g_inputIntProcAry[8] = inputProc; } else if (intcfg == INPUT10_INT_EN) { g_inputIntProcAry[9] = inputProc; } else if (intcfg == INPUT11_INT_EN) { g_inputIntProcAry[10] = inputProc; } else if (intcfg == INPUT12_INT_EN) { g_inputIntProcAry[11] = inputProc; } else if (intcfg == INPUT13_INT_EN) { g_inputIntProcAry[12] = inputProc; } else if (intcfg == INPUT14_INT_EN) { g_inputIntProcAry[13] = inputProc; } else if (intcfg == INPUT15_INT_EN) { g_inputIntProcAry[14] = inputProc; } else if (intcfg == INPUT16_INT_EN) { g_inputIntProcAry[15] = inputProc; } intconfig |= intcfg; SetInputInt(intconfig); } InputIntProc g_ecdIntProcAry[2] = {NULL}; void RegEcdInputProc(u16 ecdId, void(*ecdProc)(void)) { assert_param(IS_ECD_SEL(ecdId)); if (ecdId == ECD_SEL1) { g_ecdIntProcAry[0] = ecdProc; } else if (ecdId == ECD_SEL2) { g_ecdIntProcAry[1] = ecdProc; } } // 外部中断响应函数 void FpgaIntProc(void) { u16 tmp16; { tmp16 = GetRunStatus(); // 读到运行状态 if ((tmp16 & INPUT_ALARM_FLAG) != 0) // 输入信号下降沿中断 { //printf("Get input int, GetRunStatus=0x%x, ", tmp16); tmp16 = GetInputIntFlags(); //printf("GetInputIntFlags=0x%x\r\n", tmp16); SetVAxisConfig(VCTR_INPUT_ALM_INT); // 清除中断标志 if ((tmp16 & INPUT01_INT_FLAG) != 0) { if (g_inputIntProcAry[0] != NULL) { g_inputIntProcAry[0](); } } if ((tmp16 & INPUT02_INT_FLAG) != 0) { if (g_inputIntProcAry[1] != NULL) { g_inputIntProcAry[1](); } } if ((tmp16 & INPUT03_INT_FLAG) != 0) { if (g_inputIntProcAry[2] != NULL) { g_inputIntProcAry[2](); } } if ((tmp16 & INPUT04_INT_FLAG) != 0) { if (g_inputIntProcAry[3] != NULL) { g_inputIntProcAry[3](); } } if ((tmp16 & INPUT05_INT_FLAG) != 0) { if (g_inputIntProcAry[4] != NULL) { g_inputIntProcAry[4](); } } if ((tmp16 & INPUT06_INT_FLAG) != 0) { if (g_inputIntProcAry[5] != NULL) { g_inputIntProcAry[5](); } } if ((tmp16 & INPUT07_INT_FLAG) != 0) { if (g_inputIntProcAry[6] != NULL) { g_inputIntProcAry[6](); } } if ((tmp16 & INPUT08_INT_FLAG) != 0) { if (g_inputIntProcAry[7] != NULL) { g_inputIntProcAry[7](); } } if ((tmp16 & INPUT09_INT_FLAG) != 0) { if (g_inputIntProcAry[8] != NULL) { g_inputIntProcAry[8](); } } if ((tmp16 & INPUT10_INT_FLAG) != 0) { if (g_inputIntProcAry[9] != NULL) { g_inputIntProcAry[9](); } } if ((tmp16 & INPUT11_INT_FLAG) != 0) { if (g_inputIntProcAry[10] != NULL) { g_inputIntProcAry[10](); } } if ((tmp16 & INPUT12_INT_FLAG) != 0) { if (g_inputIntProcAry[11] != NULL) { g_inputIntProcAry[11](); } } if ((tmp16 & INPUT13_INT_FLAG) != 0) { if (g_inputIntProcAry[12] != NULL) { g_inputIntProcAry[12](); } } if ((tmp16 & INPUT14_INT_FLAG) != 0) { if (g_inputIntProcAry[13] != NULL) { g_inputIntProcAry[13](); } } if ((tmp16 & INPUT15_INT_FLAG) != 0) { if (g_inputIntProcAry[14] != NULL) { g_inputIntProcAry[14](); } } if ((tmp16 & INPUT16_INT_FLAG) != 0) { if (g_inputIntProcAry[15] != NULL) { g_inputIntProcAry[15](); } } } if ((tmp16 & ENCODER_ALARM_FLAG) != 0) // 编码器ZP信号上升沿中断 { //printf("Get zp int, GetRunStatus=0x%x, ", tmp16); tmp16 = GetEcdIntFlags(); //printf("GetInputIntFlags=0x%x\r\n", tmp16); if ((tmp16 & ECD1ZP_INT_FLAG) != 0) { SetVAxisConfig(VCTR_ZP1_INT); // 清除编码器1 ZP 中断标志 if (g_ecdIntProcAry[0] != NULL) { g_ecdIntProcAry[0](); } } if ((tmp16 & ECD2ZP_INT_FLAG) != 0) { SetVAxisConfig(VCTR_ZP2_INT); // 清除编码器2 ZP 中断标志 if (g_ecdIntProcAry[1] != NULL) { g_ecdIntProcAry[1](); } } } } } //-------------------------------------------------------------------- u16 g_exOutBuf[EXIO_PORT_NUM] = {0xffff}; void SetExoutEnOn(void) { SetVAxisConfig(EXOUT_EN_ON); } void SetExoutEnOff(void) { SetVAxisConfig(EXOUT_EN_OFF); } // 设置值 void SetExOutValue(u16 addr, u8 value) { if (addr == 0 || addr > MAX_EXIO_ADDR) { return; } if (value == Bit_SET) { g_exOutBuf[(addr-1)/EXIO_PER_PORT] |= EXIO_ADDR_MOD(addr-1); } else { g_exOutBuf[(addr-1)/EXIO_PER_PORT] &= ~(EXIO_ADDR_MOD(addr-1)); } } u8 GetExOutValue(u16 addr) { if (addr == 0 || addr > MAX_EXIO_ADDR) { return 0xff; } if ((g_exOutBuf[(addr-1)/EXIO_PER_PORT] & EXIO_ADDR_MOD(addr-1)) != 0) { return Bit_SET; } return Bit_RESET; } void FlushExOutputs(void) { u16 addr; for (addr = 0; addr < MAX_EXIO_ADDR; addr += EXIO_PER_PORT) { FmcWriteReg(EXIO_PORT_ADDR(addr), g_exOutBuf[(addr)/EXIO_PER_PORT]); } } // 设置值并输出 void SetExOutput(u16 addr, u8 value) { SetExOutValue(addr, value); #if (0) // 只刷新输出端口 FsmcWriteReg(EXIO_PORT_ADDR(addr-1), g_exOutBuf[(addr-1)/EXIO_PER_PORT]); #else // 刷新所有输出端口 FlushExOutputs(); #endif } // 读取值 u8 GetExInput(u16 addr) { if (addr == 0 || addr > MAX_EXIO_ADDR) { return Bit_SET; } return (((FmcReadReg(EXIO_PORT_ADDR(addr-1)) & EXIO_ADDR_MOD(addr-1)) != 0) ? Bit_SET : Bit_RESET); } void GetExInputs(u16 * pBuf) { int i; if (pBuf == NULL) { return; } for (i = 0; i < EXIO_PORT_NUM; i++) { pBuf[i] = FmcReadReg(EXIO_PORT_ADDR(i*EXIO_PER_PORT)); } } void TestFPGA(char * para1, char * para2) { int p1, p2; if (para1 == NULL || para2 == NULL) { return; } printf("para1=%s, para2=%s\r\n", para1, para2); p1 = 0; p2 = 0; if (strcmp(para1, "") != 0) { p1 = atoi(para1); } if (strcmp(para2, "") != 0) { p2 = atoi(para2); } if (p1 == p2) { } if (p1 == -1) { u16 val = FmcReadReg(VAXIS+p2); printf("read addr 0x%x, val=0x%x\r\n", p2, val); } else if (p1 >= 0) { FmcWriteReg(VAXIS+p1, p2); printf("write addr 0x%x, val=0x%x\r\n", p1, p2); } else if (p1 == -2) { int hardver = GetFpgaHardVersion(); printf("\r\nFPGA Hard Version = Ver %x.%x \r\n", (hardver&0xff00)>>8,(hardver&0x00ff)); int softver = GetFpgaSoftVersion(); printf("\r\nFPGA Soft Version = Ver %x.%x \r\n", (softver&0xff00)>>8,(softver&0x00ff)); } else if (p1 == -3) { printf("op counter=%d\r\n", GetOPCounter()); } else if (p1 == -4) { printf("zp counter=%d\r\n", GetZPCounter()); } else if (p1 == -5) { if (p2 == 1) { ClearEcdCounter(ECD_SEL1); printf("ClearEcd1Counter\r\n"); } else if (p2 == 2) { ClearEcdCounter(ECD_SEL2); printf("ClearEcd2Counter\r\n"); } } else if (p1 == -6) { SetOpCounter(p2); printf("SetOpCounter %d\r\n", p2); } else if (p1 == -7) { SetZpCounter(p2); printf("SetZpCounter %d\r\n", p2); } else if (p1 == -8) { SetEcdCounter(ECD_SEL1, p2); printf("SetEcd1Counter %d\r\n", p2); } else if (p1 == -9) { SetEcdCounter(ECD_SEL2, p2); printf("SetEcd2Counter %d\r\n", p2); } }