diff --git a/a.txt b/a.txt deleted file mode 100644 index e69de29..0000000 diff --git a/src/Xilinx.spec b/src/Xilinx.spec new file mode 100644 index 0000000..8eea377 --- /dev/null +++ b/src/Xilinx.spec @@ -0,0 +1,2 @@ +*startfile: +crti%O%s crtbegin%O%s diff --git a/src/ctrl_module.c b/src/ctrl_module.c new file mode 100644 index 0000000..0b3d015 --- /dev/null +++ b/src/ctrl_module.c @@ -0,0 +1,474 @@ +#include "bldc.h" +#include "ctrl_module.h" + +// ·¹Áö½ºÅÍ BIT°ª °¡Á®¿À±â +static u8_t GetBit(u8_t nIdx, u8_t cMask, u8_t cShift) +{ + u8_t cRetVal = 0; + + /* MISRA C Dir 4.14 : ·¹Áö½ºÅÍ À¯È¿¹ü À§ È®ÀÎ */ + if(nIdx > NUM_INDEX) + { +#if DEBUG_COVER + cRetVal = ERR_INDEX; + xil_printf("Ctrl_Module: Values greater than register range 13\r\n"); +#endif + } + else + { + cRetVal = (u8_t)BLDC_mReadReg(BASE_ADDR, BLDC_S00_AXI_SLV_REG0_OFFSET + (nIdx * 4u)); // ·¹Áö½ºÅÍ°ª Àаí + cRetVal = (cRetVal & cMask) >> cShift; // 0 ȤÀº 1 ¼³Á¤ + } + + return cRetVal; +} + +// ·¹Áö½ºÅÍ BIT°ª ¼³Á¤Çϱâ +static void SetBit(u8_t nIdx, u8_t cMask, u8_t cShift) +{ + u32_t cVal = 0, cVal2 = 0, cVal3 = 0x01; + + /* MISRA C Dir 4.14 : ·¹Áö½ºÅÍ À¯È¿¹ü À§ È®ÀÎ */ + if(nIdx <= NUM_INDEX) + { + cVal = (u32_t)BLDC_mReadReg(BASE_ADDR, BLDC_S00_AXI_SLV_REG0_OFFSET + (nIdx * 4u)); // ·¹Áö½ºÅÍ°ª Àаí + + if(cMask == 0x01u) + { + cVal2 = (u32_t)(cVal3 << cShift); // 1 ¼³Á¤ + cVal |= cVal2; + } + else + { + cVal2 = (u32_t)(cVal3 << cShift); // 0 ¼³Á¤ + cVal2 = ~cVal2; + cVal &= cVal2; + } + + BLDC_mWriteReg(BASE_ADDR, (BLDC_S00_AXI_SLV_REG0_OFFSET + (nIdx * 4u)), (u32)cVal); + } +} + +// ·¹Áö½ºÅÍ byte°ª °¡Á®¿À±â +static u32_t GetByte(u8_t nIdx) +{ + u32_t cRetVal = 0; + + if(nIdx <= NUM_INDEX) + { + cRetVal = BLDC_mReadReg(BASE_ADDR, BLDC_S00_AXI_SLV_REG0_OFFSET + (nIdx * 4u)); + } + else + { +#if DEBUG_COVER + cRetVal = ERR_INDEX; +#endif + } + + return cRetVal; +} + +// ·¹Áö½ºÅÍ Byte°ª ¼³Á¤Çϱâ +static void SetByte(u8_t nIdx, u8_t cData) +{ + BLDC_mWriteReg(BASE_ADDR, (BLDC_S00_AXI_SLV_REG0_OFFSET + (nIdx * 4u)), (u32)cData); +} + +// ¸®¸ðÄÁ ¿¬°á »óÅ ȮÀÎ +static void CheckOverCurrent(void) +{ + if(g_cOverCurrFlag == 0u) // °úÀü·ù ¾Ë¶÷ ¹ß»ýÇÏ¸é ·¹Áö½ºÅÍ°ª °¡Á®¿À±â ÁßÁö, ¸¶½ºÆ® »ó½Â/ÇÏ°­ ½ÃÁ¡¿¡ g_cOverCurrFlag = 0 ¼³Á¤ÇÏ°í °¡Á®¿À±â Àç½ÃÀÛ + { + g_cOverCurrFlag = (u8_t)GetBit(REG_IDX_4, REG_MASK_OVER_CURR, SHIFT_OVER_CURR); + } + else + { + if((g_cOverCurrFlag == 1u) && (g_cMastRcvCmd != 0x00u)) // °úÀü·ù ¹ß»ý ÈÄ ¸¶½ºÆ® »óÅ°¡ Á¤Áö°¡ ¾Æ´Ñ °æ¿ì¸¸ (1ȸ ÁøÀÔ¿ë) + { + SetBit(REG_IDX_7, 0x01, SHIFT_MAST_OVER_CURR); // 01. ¸ðÅÍ °úÀü·ù Ŭ¸®¾î, Register8, High, bit3 + + g_cMastRcvCmd = 0x00u; // 02. ¸¶½ºÆ® Á¤Áö + SetMotor(g_cMastRcvCmd); // Motor Up/Down/Stop ±¸µ¿ Á¦¾î + + SetBit(REG_IDX_7, 0x00, SHIFT_MAST_OVER_CURR); // 03. ¸ðÅÍ °úÀü·ù Ŭ¸®¾î, Register8, Low, bit3 + } + } +} + +// ¿£ÄÚ´õ °ª ÀÏÄ¡ È®ÀÎ +static void CheckEncoder(void) +{ + g_cEncoderErrFlag = (u8_t)GetBit(REG_IDX_4, REG_MASK_ENCODER_ERR, SHIFT_ENCODER_ERR); + + g_cEncoderHWResetFlag = (u8_t)GetBit(REG_IDX_4, REG_MASK_ENCODER_HW_RESET, SHIFT_ENCODER_HW_RESET); // ³ôÀÌ°ª H/W ¸®¼Â ÀÔ·Â °Ë»ç + + if(g_cEncoderHWResetFlag == 1u) + { + SetBit(REG_IDX_7, 0x01, SHIFT_ENCODER_HW_RESET_CLEAR); // ¿£ÄÚ´õ H/W Reset Clear Set, Register7 + + g_cEncoderHWResetFlag = 0; + g_nEncoderMT = 0; + g_nMastCurrHeight = 0; + SaveEncoderMT((u32)g_nEncoderMT); // ¿£ÄÚ´õ ¸ÖƼÅÏ°ª ¾²±â + + SetBit(REG_IDX_7, 0x00, SHIFT_ENCODER_HW_RESET_CLEAR); // ¿£ÄÚ´õ H/W Reset Clear Reset, Register7 + } +} + +// Bit 3 : ¸ðÅÍ°úÀü·ù g_cOverCurrFlag +// Bit 2 : ³ôÀÌ°ª Ç¥½Ã¿ë ¿£ÄÚ´õ üũ g_cEncoderErrFlag +// Bit 1 : ¸¶½ºÆ® ±¸µ¿ üũ 0 +// Bit 0 : ¾ÈÅ׳ª¸¶½ºÆ®-ÀÓ¹«ÅëÁ¦±â Åë½Å ¼ö½Å g_cBitDetailHBErr +// BIT »óÅ ȮÀÎ +static void CheckBitDetailInfo(void) +{ + u8_t cData = 0u; + + cData = 0x01u; + if(g_cBitDetailHBErr == 1u) // ¾ÈÅ׳ª¸¶½ºÆ®-ÀÓ¹«ÅëÁ¦±â Åë½Å ¼ö½Å, Bit: 0 + { + g_cBitDetail |= cData; + } + else + { + cData = ~cData; + g_cBitDetail &= cData; + } + + cData = 0x02; + if((g_cBitDetailHBErr == 1u) || (g_cEncoderErrFlag == 1u) || (g_cOverCurrFlag == 1u)) // ¸¶½ºÆ® ±¸µ¿Ã¼Å©(Åë½Å or ¿£ÄÚ´õ or °úÀü·ù) üũ, Bit: 1 24.09.25 BIT »ç¾ç ÀçÁ¤ÀÇ + { + g_cBitDetail |= cData; + } + else + { + cData = ~cData; + g_cBitDetail &= cData; + } + + cData = 0x04; + if(g_cEncoderErrFlag == 1u) // ³ôÀÌ°ª Ç¥½Ã¿ë ¿£ÄÚ´õ üũ, Bit: 2 + { + g_cBitDetail |= cData; + } + else + { + cData = ~cData; + g_cBitDetail &= cData; + } + + cData = 0x08; + if(g_cOverCurrFlag == 1u) // ¸ðÅÍ°úÀü·ù, Bit: 3 + { + g_cBitDetail |= cData; + } + else + { + cData = ~cData; + g_cBitDetail &= cData; + } +} + +// ÇöÀç³ôÀÌ°ª È®ÀÎ +static void CheckCurrHeight(void) +{ + u32_t nRetVal = 0, nVal, nData; + float32 fUpper, fLower, fData; + + nRetVal = BLDC_mReadReg(BASE_ADDR, BLDC_S00_AXI_SLV_REG6_OFFSET); // Encoder°ª °¡Á®¿À±â + g_nEncoderMT = nRetVal; + /* Encoder°ª °è»ê */ + nData = nRetVal & SINGLE_CYCLE_MAST; + fLower = (float32)nData; // ´ÜȸÀü °ª °áÁ¤(¼Ò¼öÁ¡ Á¦¿Ü) 0 ~ 1023: 0 ~ 32.0mm(0.0 ~ 31.97) + fLower = fLower * (float32)SINGLE_BASE_SCALE; + + nData = nRetVal & MULTI_CYCLE_MAST; + nData = nData >> 10u; + fUpper = (float32)(nData); // ´ÙȸÀü °ª °áÁ¤ + + fData = fUpper * (float32)SINGLE_CYCLE_SCALE; + fData = fData + fLower; + nVal = (u32_t)fData; + + /* MISRA C Dir 4.14 : ¸¶½ºÆ® ³ôÀÌ ÃÖ´ë°ª ÃÊ°ú ½Ã ¿¹¿Üó¸® */ + if(nVal > ANT_MAST_HEIGHT_MAX) + { + g_nMastCurrHeight = ANT_MAST_HEIGHT_MAX; + } + else + { + g_nMastCurrHeight = nVal; + } + + /* ÃÖ´ë/ÃÖ¼Ò°ª µµ´Þ ½Ã ¸ØÃã ó¸® */ + if(g_cMastRcvCmd == (u8_t)CMD_MOTOR_CTN_UP) // »ó½Â Áß + { + if(g_nMastCurrHeight >= ANT_MAST_HEIGHT_MAX) // ÃÖ´ë°ª µµ´Þ + { + g_cMastRcvCmd = (u8_t)CMD_MOTOR_STOP; // ¸¶½ºÆ® Åë½Å Ä¿¸Çµå º¯°æ + SetMotor(g_cMastRcvCmd); // ¸¶½ºÆ® Stop + } + } + + if(g_cMastRcvCmd == (u8_t)CMD_MOTOR_CTN_DOWN) // ÇÏ°­ Áß + { + if(g_nMastCurrHeight <= ANT_MAST_HEIGHT_MIN) // ÃÖ¼Ò°ª µµ´Þ + { + g_cMastRcvCmd = (u8_t)CMD_MOTOR_STOP; // ¸¶½ºÆ® Åë½Å Ä¿¸Çµå º¯°æ + SetMotor(g_cMastRcvCmd); // ¸¶½ºÆ® Stop + } + } + + if(g_cMastRcvCmd == (u8_t)CMD_MOTOR_USER_INPUT) // À¯Àú ÀԷ°ª µ¿ÀÛ Áß + { + if(g_cMastAction == (u8_t)DIR_MOTOR_UP) // »ó½Â Áß + { + if(g_nMastCurrHeight >= (g_nSetMastHeight - 30u)) // ¸¶½ºÆ® ¼Óµµ °¨¾ÈÇÑ offset°ª + { + g_cMastRcvCmd = (u8_t)CMD_MOTOR_STOP; // ¸¶½ºÆ® Åë½Å Ä¿¸Çµå º¯°æ + SetMotor(g_cMastRcvCmd); // ¸¶½ºÆ® Stop + } + } + if(g_cMastAction == (u8_t)DIR_MOTOR_DOWN) // ÇÏ°­ Áß + { + if(g_nMastCurrHeight <= (g_nSetMastHeight + 30u)) + { + g_cMastRcvCmd = (u8_t)CMD_MOTOR_STOP; // ¸¶½ºÆ® Åë½Å Ä¿¸Çµå º¯°æ + SetMotor(g_cMastRcvCmd); // ¸¶½ºÆ® Stop + } + } + } + +#if DEBUG_CTRL_MODULE + xil_printf("g_nMastCurrHeight:%d, g_nSetMastHeight:%d, nRetVal:%d, fLower:%d, fUpper:%d, g_cMastRcvCmd:%d, g_cMastAction:%d\r\n", + (u32_t)g_nMastCurrHeight, (u32_t)g_nSetMastHeight, (u32_t)nRetVal, (u32_t)fLower, (u32_t)fUpper, (u32_t)g_cMastRcvCmd, (u32_t)g_cMastAction); +#endif +} + +// ¸¶½ºÆ® ±¸µ¿ Á¦¾î(Stop, Up, Down: 0x00, 0x01, 0x02) +// ControlItem(1) 0xC0: »ç¿ëÀÚ ÀÔ·Â, 0x80: ¿¬¼Ó »ó½Â, 0x40: ¿¬¼Ó ÇÏ°­, 0x00: ÁßÁö +// »ó½Â/ÇÏ°­ Áß ¿ª¹æÇâ µ¿ÀÛ ¸í·É ¼ö½Å ½Ã Á¤ÁöÇÏ´Â »ç¾ç Ãß°¡ 24.04.07 +// Á¤Áö ¸í·É Á¦¿ÜÇÏ°í DevicePowerRequest°ª¿¡ µû¶ó µ¿ÀÛ Â÷´Ü Á¶°Ç Ãß°¡ 24.05.10 +void SetMotor(u8_t cCmd) +{ + if(cCmd == (u8_t)CMD_MOTOR_STOP) // 01. 0x00 ¸ØÃã + { + if(g_cMastAction == DIR_MOTOR_UP) // 1-1 ÇöÀç »óÅ »ó½Â Áß + { + g_cMastAction = (u8_t)DIR_MOTOR_STOP_FOR_UP; // »ó½ÂÀÇ Á¤Áö + } + else // 1-2 ÇöÀç »óÅ ÇÏ°­ Áß + { + g_cMastAction = (u8_t)DIR_MOTOR_STOP_FOR_DOWN; // ÇÏ°­ÀÇ Á¤Áö + } + g_nEcdeepromCnt = 0; // ÀúÀå ÆÇÁ¤¿ë Ä«¿îÅÍ ÃʱâÈ­ + g_cEncoderSaveFlag = 1; // ¿£ÄÚ´õ ¸ÖƼÅÏ°ª eeprom ±â·Ï ÆÇÁ¤ + } + if((cCmd == (u8_t)CMD_MOTOR_CTN_UP) && (g_cCmdPowerOff == 0u)) // 02. 0x80 »ó½Â, DevicePowerRequest°ª È®ÀÎ + { + if(g_cMastAction == (u8_t)DIR_MOTOR_DOWN) // 2-1 ÇöÀç »óÅ ÇÏ°­ Áß + { + g_cMastAction = (u8_t)DIR_MOTOR_STOP_FOR_DOWN; // ÇÏ°­ÀÇ Á¤Áö + g_nEcdeepromCnt = 0; // ÀúÀå ÆÇÁ¤¿ë Ä«¿îÅÍ ÃʱâÈ­ + g_cEncoderSaveFlag = 1; // ¿£ÄÚ´õ ¸ÖƼÅÏ°ª eeprom ±â·Ï ÆÇÁ¤ + + g_cMastRcvCmd = 0x00u; // ¾ÈÅ׳ª¸¶½ºÆ® ´ë±â Áß + } + else // 2-2 ±× ¿Ü + { + g_cMastAction = (u8_t)DIR_MOTOR_UP; // »ó½Â + } + } + if((cCmd == (u8_t)CMD_MOTOR_CTN_DOWN) && (g_cCmdPowerOff == 0u)) // 03. 0x40 ÇÏ°­, DevicePowerRequest°ª È®ÀÎ + { + if(g_cMastAction == (u8_t)DIR_MOTOR_UP) // 3-1 ÇöÀç »óÅ »ó½Â Áß + { + g_cMastAction = (u8_t)DIR_MOTOR_STOP_FOR_UP; // »ó½ÂÀÇ Á¤Áö + g_nEcdeepromCnt = 0; // ÀúÀå ÆÇÁ¤¿ë Ä«¿îÅÍ ÃʱâÈ­ + g_cEncoderSaveFlag = 1; // ¿£ÄÚ´õ ¸ÖƼÅÏ°ª eeprom ±â·Ï ÆÇÁ¤ + + g_cMastRcvCmd = 0x00u; // ¾ÈÅ׳ª¸¶½ºÆ® ´ë±â Áß + } + else // 3-2 ±× ¿Ü + { + g_cMastAction = (u8_t)DIR_MOTOR_DOWN; // ÇÏ°­ + } + } + if((cCmd == (u8_t)CMD_MOTOR_USER_INPUT) && (g_cCmdPowerOff == 0u)) // 04. 0xC0 »ç¿ëÀÚ ÀÔ·Â, DevicePowerRequest°ª È®ÀÎ + { + if(g_nMastCurrHeight < g_nSetMastHeight) // 4-1 ÇöÀç ³ôÀÌ°¡ ¸ñÇ¥ ³ôÀ̺¸´Ù ³·À¸¸é »ó½Â + { + if(g_cMastAction == (u8_t)DIR_MOTOR_DOWN) // 4-1-1 ÇöÀç »óÅ ÇÏ°­ Áß + { + g_cMastAction = (u8_t)DIR_MOTOR_STOP_FOR_DOWN; // ÇÏ°­ÀÇ Á¤Áö + g_nEcdeepromCnt = 0; // ÀúÀå ÆÇÁ¤¿ë Ä«¿îÅÍ ÃʱâÈ­ + g_cEncoderSaveFlag = 1; // ¿£ÄÚ´õ ¸ÖƼÅÏ°ª eeprom ±â·Ï ÆÇÁ¤ + + g_cMastRcvCmd = 0x00u; // ¾ÈÅ׳ª¸¶½ºÆ® ´ë±â Áß + } + else // 4-1-2 ±× ¿Ü + { + g_cMastAction = (u8_t)DIR_MOTOR_UP; // »ó½Â + } + } + else // 4-2 ÇöÀç ³ôÀÌ°¡ ¸ñÇ¥ ³ôÀ̺¸´Ù ³ô°Å³ª °°À¸¸é ÇÏ°­ + { + if(g_cMastAction == (u8_t)DIR_MOTOR_UP) // 4-2-1 ÇöÀç »óÅ »ó½Â Áß + { + g_cMastAction = (u8_t)DIR_MOTOR_STOP_FOR_UP; // »ó½ÂÀÇ Á¤Áö + g_nEcdeepromCnt = 0; // ÀúÀå ÆÇÁ¤¿ë Ä«¿îÅÍ ÃʱâÈ­ + g_cEncoderSaveFlag = 1; // ¿£ÄÚ´õ ¸ÖƼÅÏ°ª eeprom ±â·Ï ÆÇÁ¤ + + g_cMastRcvCmd = 0x00u; // ¾ÈÅ׳ª¸¶½ºÆ® ´ë±â Áß + } + else // 4-2-2 ±× ¿Ü + { + g_cMastAction = (u8_t)DIR_MOTOR_DOWN; // ÇÏ°­ + } + } + } + + if((g_cMastAction == (u8_t)DIR_MOTOR_UP) || (g_cMastAction == (u8_t)DIR_MOTOR_STOP_FOR_UP) + || (g_cMastAction == (u8_t)DIR_MOTOR_DOWN) || (g_cMastAction == (u8_t)DIR_MOTOR_STOP_FOR_DOWN)) // À¯È¿ÇÑ ¸í·É¸¸ ¼öÇà + { + BLDC_mWriteReg(BASE_ADDR, BLDC_S00_AXI_SLV_REG2_OFFSET, (u32)g_cMastAction); // ¸¶½ºÆ® µ¿ÀÛ °áÁ¤ + } + +#if DEBUG_CTRL_MODULE + xil_printf("SetMotor: cCmd:%d, g_cMastAction:%d\r\n", (u32_t)cCmd, (u32_t)g_cMastAction); +#endif +} + +// LED Á¦¾î (¾Ë¶÷, ¸¶½ºÆ® ±¸µ¿) +static void SetLEDControl(void) +{ + u32_t cData = 0u, cMotor = 0u; + + cData = GetByte(REG_IDX_7); // LED Á¦¾î ·¹Áö½ºÅÍ°ª °¡Á®¿À±â + + if((g_cBitDetail & BIT_DETAIL_STATUS_OVER_CURR) == BIT_DETAIL_STATUS_OVER_CURR) // °úÀü·ù ¾Ë¶÷, 250mSec Áֱ⠵¿ÀÛÀ¸·Î 500mSec ¸¶´Ù ±ôºýÀÓ Ã³¸® + { + switch (g_cMotorLedFlickerCnt) + { + case 0: cMotor = LED_MOTOR_ON; break; + case 1: cMotor = LED_MOTOR_OFF; break; + default: cMotor = LED_MOTOR_OFF; break; + } + + if(g_cMotorLedFlickerCnt < 1u) + { + g_cMotorLedFlickerCnt++; + } + else + { + g_cMotorLedFlickerCnt = 0u; + } + } + else // ¸ðÅÍ ±¸µ¿ + { + if((g_cMastAction == DIR_MOTOR_UP) || (g_cMastAction == DIR_MOTOR_DOWN)) + { + cMotor = LED_MOTOR_ON; + } + else + { + cMotor = LED_MOTOR_OFF; + } + } + + if(cMotor == 1u) + { + cData |= (1u << 0u); // 0: ÀÚ¸®¼ö + } + else + { + cData &= ~(1u << 0u); + } + + SetByte(REG_IDX_7, (u8_t)cData); // µÎ°¡Áö »óÅ Àû¿ë ÈÄ LED ó¸® +} + +// ¸¶½ºÆ® ¿£ÄÚ´õ ¸ÖƼÅÏ°ª ¼¼Æà +static void SetEncoderMT(void) +{ + BLDC_mWriteReg(BASE_ADDR, (BLDC_S00_AXI_SLV_REG0_OFFSET + (5u * 4u)), (u32)g_nEncoderMT); + + SetBit(REG_IDX_5, 0x01, SHIFT_ENCODER_WRITE); // Encoder°ª Register¿¡ ±â·Ï Flag +} + +// Á¦¾îºÎ ¸ðµâ Ãʱ⠼³Á¤ +void InitCtrlModule(void) +{ + u32 cData; + g_cMastRcvCmd = (u8_t)CMD_MOTOR_STOP; + g_cMastAction = (u8_t)DIR_MOTOR_STOP_FOR_UP; + g_cCMProcessIdx = 0; + g_cCmdPreparePowerOff = 0; + g_cCmdPowerOff = 0; + g_cMotorLedFlickerCnt = 0; // ¸ðÅÍ LED ±ôºýÀÓ Ä«¿îÅÍ + + g_cBitDetailHBErr = 0; // Heart Beat ¼ö½Å Off ÆÇÁ¤ + g_cOverCurrFlag = 0; // °úÀü·ù ¹ß»ý ¿©ºÎ + g_cEncoderHWResetFlag = 0; + + SetEncoderMT(); // ¸¶½ºÆ® ¿£ÄÚ´õ ¸ÖƼÅÏ°ª ¼¼ÆÃ, eeprom¿¡¼­ ÀÐÀº°ªÀ» register¿¡ ±â·Ï +} + +// Á¦¾îºÎ ¸ðµâ µ¿ÀÛ Ã³¸® +void CtrlModuleProcess(void) +{ + if(g_nCnt2 > TIMER_MSEC250) + { + g_nCnt2 = 0; + CheckCurrHeight(); // ÇöÀç³ôÀÌ°ª È®ÀÎ + switch(g_cCMProcessIdx) // ºÐ»ê ó¸® + { + case 0: SetLEDControl(); break; // LED Á¦¾î (¾Ë¶÷, ¸¶½ºÆ® ±¸µ¿) + case 1: CheckOverCurrent(); break; // °úÀü·ù »óÅ ȮÀÎ + case 2: CheckEncoder(); break; // ¿£ÄÚ´õ °ª ÀÏÄ¡ È®ÀÎ + case 3: CheckBitDetailInfo(); break; // BIT »óÅ ȮÀÎ + default: break; + } + + g_cCMProcessIdx++; + if(g_cCMProcessIdx > 3u) + { + g_cCMProcessIdx = 0; + } + } + + if(g_cEncoderSaveFlag == 0u) // eeprom ÀúÀå Á¶°ÇÀÌ ¾Æ´Ï¸é Ä«¿îÅÍ ÃʱâÈ­ + { + g_nEcdeepromCnt = 0u; + } + else // eeprom ÀúÀå Á¶°Ç ¸¸Á· + { + if(g_nEcdeepromCnt > TIMER_SEC3) + { + g_cEncoderSaveFlag = 0u; // ÀçÁøÀÔ ¹æÁö + g_nEcdeepromCnt = 0u; + SaveEncoderMT((u32)g_nEncoderMT); // ¿£ÄÚ´õ ¸ÖƼÅÏ°ª ¾²±â + } + } +} + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ctrl_module.h b/src/ctrl_module.h new file mode 100644 index 0000000..ad7bbb2 --- /dev/null +++ b/src/ctrl_module.h @@ -0,0 +1,58 @@ +#ifndef CTRL_MODULE_H +#define CTRL_MODULE_H + +#include "xil_io.h" +#include "define.h" +#include "main.h" +#include "tcp_client.h" + + + +static u32_t g_cCMProcessIdx; // CtrlModuleProcess ¼øÂ÷ ÁøÇà 󸮿ë À妽º + +u32_t g_nMastCurrHeight; // ¸¶½ºÆ® ÇöÀç ³ôÀÌ(0 ~ 570cm) +u8_t g_cMastRcvCmd; // ¸ðÅÍ Á¦¾î ¼ö½Å ¸í·É(Bit0:¸ØÃã, Bit1:¿¬¼ÓÇÏ°­, Bit2:¿¬¼Ó»ó½Â, Bit3:ÃÖ´ë¼öÃà, Bit4: ÃÖ´ëÈ®Àå, Bit5:»ç¿ëÀÚ ÀÔ·Â) +static u8_t g_cMastAction; // FPGA¿¡ »ç¿ëÇÒ ¸¶½ºÆ® ÇöÀç ±¸µ¿ »óÅÂ(Stop, Up, Down: 0x00, 0x01, 0x02) +u8_t g_cBitDetail; // BIT Detail Á¤º¸ + +u32_t g_nSetMastHeight; // ¸¶½ºÆ® ¸ñÇ¥ ³ôÀÌ +static u8_t g_cRmtConn; // ¸®¸ðÄÁ ¿¬°á ¿©ºÎ + +u8_t g_cMastPeriodSendCmd; // DeviceStart_Request ¼ö½Å Ä¿¸Çµå, ÀÌ¿ëó: AntMastStatus_Report(UDP), AntMastCBIT_Report, Á¤±â º¸°í È°¼º/ºñÈ°¼º +u8_t g_cDeviceErase; // DeviceErase ¼³Á¤°ª +static u8_t g_cMastPowerCtrlRcvCmd; // DevicePower_Reqeust ¼ö½Å Ä¿¸Çµå, 0x05:Àü¿ø Off Áغñ, 0x06: Àü¿ø Off, 0x01: Àü¿ø Off Ãë¼Ò, 0x07: Àü¿ø On +u8_t g_cCmdPreparePowerOff; // DevicePower_Request °ü·Ã º¯¼ö, 1: Set, 0: Reset 0x05: Àü¿ø Off Áغñ, 0x01: Àü¿ø Off Ãë¼Ò +u8_t g_cCmdPowerOff; // DevicePower_Request °ü·Ã º¯¼ö, 1: Set, 0: Reset 0x06: Àü¿ø Off, 0x07: Àü¿ø On +u32_t g_nEncoderMT; // ¿£ÄÚ´õ ¸ÖƼÅÏ°ª X, ¿£ÄÚ´õ Àüü°ª(24.09.10) +static u8_t g_cEncoderSaveFlag; // ¿£ÄÚ´õ ¸ÖƼÅÏ°ª ±â·Ï ¿©ºÎ ÆÇÁ¤ 0: ´ë±â, 1: ±â·Ï +u8_t g_cMotorLedFlickerCnt; // ¸ðÅÍ LED ±ôºýÀÓ Ä«¿îÅÍ + +u32_t g_nCnt2; // Á¦¾îºÎ ¸ðµâ µ¿ÀÛ Ã³¸®¿ë Ä«¿îÅÍ +u32_t g_nEcdeepromCnt; // ¿£ÄÚ´õ ¸ÖƼÅÏ eeprom ±â·Ï¿ë Ä«¿îÅÍ + +u32_t g_nBitDetailHBCnt; // ÀÓ¹«Ã³¸®¿¡¼­ Heart Beat ¼ö½ÅµÇ´ÂÁö ÆÇ´ÜÇÏ´Â Ä«¿îÅÍ(BIT DetailÀÇ ÀÓ¹«Ã³¸®¿ÍÀÇ Åë½Å »óÅ°ª °áÁ¤) +u8_t g_cBitDetailHBErr; // Heart Beat ¼ö½Å Off ÆÇÁ¤ +u8_t g_cOverCurrFlag; // °úÀü·ù ¹ß»ý ¿©ºÎ +u8_t g_cEncoderErrFlag; // ¿£ÄÚ´õ °ª ºÒÀÏÄ¡ ¿©ºÎ +u8_t g_cEncoderHWResetFlag; // ¿£ÄÚ´õ ¿µÁ¡ ¼³Á¤ ¿©ºÎ(PBA »ó Set Origin) + +static u8_t GetBit(u8_t nIdx, u8_t cMask, u8_t cShift); // ·¹Áö½ºÅÍ BIT°ª °¡Á®¿À±â +static void SetBit(u8_t nIdx, u8_t cMask, u8_t cShift); // ·¹Áö½ºÅÍ BIT°ª ¼³Á¤Çϱâ +static u32_t GetByte(u8_t nIdx); // ·¹Áö½ºÅÍ byte°ª °¡Á®¿À±â +static void SetByte(u8_t nIdx, u8_t cData); // ·¹Áö½ºÅÍ byte°ª ¼³Á¤Çϱâ + +static void CheckOverCurrent(void); // °úÀü·ù »óÅ ȮÀÎ +static void CheckEncoder(void); // ¿£ÄÚ´õ °ª ÀÏÄ¡ È®ÀÎ +static void CheckBitDetailInfo(void); // BIT Detail »óÅ ȮÀÎ +static void CheckCurrHeight(void); // ÇöÀç³ôÀÌ°ª È®ÀÎ + +void SetMotor(u8_t cCmd); // ¸¶½ºÆ® ±¸µ¿ Á¦¾î(Stop, Up, Down: 0x00, 0x01, 0x02) +static void SetLEDControl(void); // LED Á¦¾î (¾Ë¶÷, ¸¶½ºÆ® ±¸µ¿) + +static void SetEncoderMT(void); // ¸¶½ºÆ® ¿£ÄÚ´õ ¸ÖƼÅÏ°ª ¼¼Æà + +void InitCtrlModule(void); // Á¦¾îºÎ ¸ðµâ Ãʱ⠼³Á¤ +void CtrlModuleProcess(void); // Á¦¾îºÎ ¸ðµâ µ¿ÀÛ Ã³¸® + + +#endif // CTRL_MODULE_H diff --git a/src/define.h b/src/define.h new file mode 100644 index 0000000..10bb566 --- /dev/null +++ b/src/define.h @@ -0,0 +1,230 @@ +#ifndef DEFINE_H +#define DEFINE_H + +#define VER_VERSION 1u +#define VER_UPDATE 0u +#define VER_TEST 7u +#define VER_COMPILE 0u + +#define TEST_LOG_ON 1u +#define TEST_LOG_ON_UDP 0u +#define DEBUG_CTRL_MODULE 0u +#define DEBUG_COVER 0u + + +typedef float float32; +//--------------------------------------------------------------------------------------------- +//-----------------------------------------ctrl_module----------------------------------------- +#define BASE_ADDR 0x43C00000u +#define NUM_INDEX 13u // 0 ~ 8, 9 ~ 12(EEPROM ¿ªÇÒ) +#define ERR_INDEX 0u + +#define ARR_BUF_MARGIN 4u + +#define TIMER_BASE 30000u +#define TIMER_MSEC250 27u +#define TIMER_MSEC333 35u +#define TIMER_MSEC500 53u +#define TIMER_SEC1 105u +#define TIMER_SEC2 210u +#define TIMER_SEC3 315u +#define TIMER_SEC5 525u +#define TIMER_SEC10 1050u + + +// Motor ¸í·É +#define CMD_MOTOR_USER_INPUT 0xC0u +#define CMD_MOTOR_CTN_UP 0x80u +#define CMD_MOTOR_CTN_DOWN 0x40u +#define CMD_MOTOR_STOP 0x00u + +// Motor ¹æÇâ +#define DIR_MOTOR_STOP_FOR_UP 0x00u +#define DIR_MOTOR_UP 0x01u +#define DIR_MOTOR_DOWN 0x02u +#define DIR_MOTOR_STOP_FOR_DOWN 0x03u +//#define BIT_MOTOR_STOP 0x00 + +// Diagnostic »óÅ +#define NUM_DIAG_MEMBER 5u // Power On(7), Current Mon, Ethernet, Motor Init, Motor Pos(3) +#define BIT_MOTOR_POS 0x08u // Motor Position +#define BIT_MOTOR_INIT 0x10u // Motor Initialization +#define BIT_ETHERNET 0x20u +#define BIT_CURR_MON 0x40u +#define BIT_POWER_ON 0x80u + +// Motor »óÅ +#define NUM_MOTOR_MEMBER 4u // Motor Up, Down, Min Height Arrive, Max Height Arrive +#define BIT_MOTOR_UP 0x01u // Register Index 3 +#define BIT_MOTOR_DOWN 0x02u +#define BIT_MOTOR_MIN_ARRIVE 0x04u +#define BIT_MOTOR_MAX_ARRIVE 0x10u + +// BIT DETAIL »óÅ +#define NUM_BIT_DETAIL_MEMBER 4u +#define BIT_DETAIL_STATUS_ENCODER 0x04u +#define BIT_DETAIL_STATUS_OVER_CURR 0x08u + +// BIT »óÅ +#define REG_MASK_OVER_CURR 0x04u // REG_IDX_4 +#define REG_MASK_ENCODER_ERR 0x40u +#define REG_MASK_ENCODER_HW_RESET 0x80u + +// Á¦¾î +#define REG_MASK_ENCODER_HW_CLEAR 0x10u // REG_IDX_7 + +// ¸ðÅÍ ³ôÀÌ +//#define SINGLE_CYCLE_SCALE 21u // 0 ~ 1023: 0 ~ 32mm +#define SINGLE_CYCLE_SCALE 21.476 // 0 ~ 1023: 0 ~ 21.51mm +#define SINGLE_BASE_SCALE 0.021 +#define SINGLE_CYCLE_MAST 0x000003FFu // À¯È¿bit: 10bit(0 ~ 1023) +#define MULTI_CYCLE_MAST 0x007FFC00u // À¯È¿bit: 12bit(0 ~ 4095) +#define ANT_MAST_HEIGHT_MAX 5700u // 5700mm +#define ANT_MAST_HEIGHT_MIN 0u // 0mm + +// À¯¼±Á¶Á¤±â, Àü¿øÁ¦¾î, ¼Ò°ÅÁ¦¾î +#define SHIFT_REMOCON_ON 00u // bit À̵¿ +//#define SHIFT_POWER_CTRL 0x01u +#define SHIFT_DELETE_CTRL 02u + +#define SHIFT_ENCODER_WRITE 24u // 24 ¹ø° bit + +#define BIT_REMOCON_ON 0x01u // bit À§Ä¡ +//#define BIT_POWER_CTRL 0x02u +#define BIT_DELETE_CTRL 0x04u + +// LED »óÅ ¼³Á¤ +//#define LED_ALARM_ON 0x04u +#define LED_MOTOR_ON 0x01u +#define LED_MOTOR_OFF 0x00u +#define LED_ALL_OFF 0x00u + +// Mast ¿µÁ¡ ¼³Á¤ +#define SHIFT_MAST_ORIGIN 0x02u + +// °úÀü·ù Ŭ¸®¾î +#define SHIFT_MAST_OVER_CURR 0x03u + +// °úÀü·ù ¾Ë¶÷ +#define SHIFT_OVER_CURR 0x02u + +// ¿£ÄÚ´õ °ª ºÒÀÏÄ¡ ¾Ë¶÷ +#define SHIFT_ENCODER_ERR 0x06u + +// ¿£ÄÚ´õ H/W ¸®¼Â +#define SHIFT_ENCODER_HW_RESET 7u + +// ¿£ÄÚ´õ HW ¸®¼Â Ŭ¸®¾î +#define SHIFT_ENCODER_HW_RESET_CLEAR 4u + +// UDP Åë½Å Ä¿¸Çµå +#define TCP_CMD_PERIOD_REPORT_STOP 0x00u +#define TCP_CMD_PERIOD_REPORT_START 0x40u + + +// TCP/IP Åë½Å +// TCP MSG - TYPE +#define IDC_CMD_TYPE_DEVICE_PBIT 0x98u +#define IDC_CMD_TYPE_BIT_DETAIL 0x9Au +#define IDC_CMD_TYPE_MAST_CONTROL 0x9Bu +#define IDC_CMD_TYPE_DEVICE_ERASE 0x91u +#define IDC_CMD_TYPE_DEVICE_POWER 0x91u + + +// UDP MSG TYPE +#define IDC_CMD_TYPE_STATUS_REPORT 0x90u +#define IDC_CMD_TYPE_HEART_BEAT 0x92u +#define IDC_CMD_TYPE_CBIT_REPORT 0x99u + +// ICD Sour/Dest Unit +#define ICD_CMD_UNIT_MP 0x61u +#define ICD_CMD_UNIT_MAST 0x40u + +// ICD TM +#define ICD_CMD_TM_TCP 0x24u +#define IDC_CMD_TM_UDP 0x04u + +// Simmulation Alarm +#define ICD_CMD_SIM_ALARM_RESET 0x00u // ¾Ë¶÷ ½ÇÁ¦ ¸ðµå +#define ICD_CMD_SIM_ALARM_SET 0x01u // ¾Ë¶÷ °¡»ó ¸ðµå +//--------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------- + +//--------------------------------------------------------------------------------------------- +//----------------------------------------tcp/ip setting--------------------------------------- +//main.c¿¡ defineµÈ DEFAULT_IP_ADDRESS, DEFAULT_IP_MASK, DEFAULT_GW_ADDRESS¸¦ ÇÔ²² º¯°æ +#define MY_IP_ADDR1 172u +#define MY_IP_ADDR2 16u +#define MY_IP_ADDR3 0u +#define MY_IP_ADDR4 50u + +#define IPINFO_SIZE 6u + +#define CHAR_SOUR 0x61u + +//----------------------------------------TCP Server------------------------------------------- +#define NUM_TCP_CLIENT 2u +#define NUM_RECV_BUF 400u + +#define MIN_TCP_SER_RCV_LEN 10u // À¯È¿ÇÑ ÃÖ¼Ò ÆÐŶ »çÀÌÁî +#define LEN_COMPARE 3u // À¯È¿ ÆÐŶ °Ë»ç »çÀÌÁî +#define LEN_ANT_MAST_START_REQ 10u // DeviceStart_Request Length +#define LEN_DEVICE_PBIT_REQ 10u // DevicePBIT_Request Length +#define LEN_DEVICE_BIT_DETAIL_REQ 11u // DeviceBITdetail_Request Length +#define LEN_ANT_MAST_CONTROL_REQ 11u // AntMastControl_Request Length, °¡º¯, 8 ~ 12(Äڵ忡¼­ ó¸®) +#define LEN_DEVICE_ERASE_REQ 11u // DeviceErase_Request Length +#define LEN_DEVICE_POWER_REQ 11u // DevicePower_Request Length + +#define LEN_SIM_ALARM_SET_REQ 12u // SimAlarmSet_Request Length +#define LEN_MAST_ORIGIN_SET_REQ 10u // MastOrigin_Set_Request Length + +//----------------------------------------TCP Client------------------------------------------- +#define TCP_CLIENT_MY_PORT 61501u // TCP Client »ç¿ë 24.06.27 + +#define TCP_MP_IP_ADDR1 172u // ÀÓ¹«ÅëÁ¦±â ³»ºÎ IP Address +#define TCP_MP_IP_ADDR2 16u +#define TCP_MP_IP_ADDR3 0u +#define TCP_MP_IP_ADDR4 20u +#define TCP_MP_PORT 61202U // ÀÓ¹«ÅëÁ¦±â ³»ºÎ Port + +//----------------------------------------UDP Client------------------------------------------- +#define UDP_SERVER_IP_ADDRESS "172.16.0.20" // 172.16.x.x +#define UDP_SERVER_IP_ADDR1 172u +#define UDP_SERVER_IP_ADDR2 16u +#define UDP_SERVER_IP_ADDR3 0u +#define UDP_SERVER_IP_ADDR4 20u +#define UDP_SERVER_PORT 60202u // º¯°æ 24.06.27 +#define UDP_MY_PORT 61501u + +#define LEN_ANT_MAST_STATUS_REPORT 15u +#define LEN_ANT_MAST_CBIT_REPORT 12u +#define LEN_HEART_BEAT_DATA 11u +//--------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------- + +// REGISTER INDEX +#define REG_IDX_0 0u +#define REG_IDX_1 1u +#define REG_IDX_2 2u +#define REG_IDX_3 3u +#define REG_IDX_4 4u +#define REG_IDX_5 5u +#define REG_IDX_6 6u +#define REG_IDX_7 7u +#define REG_IDX_8 8u +#define REG_IDX_9 9u +#define REG_IDX_10 10u +#define REG_IDX_11 11u +#define REG_IDX_12 12u + + + +#define IIC_SCLK_RATE 100000u +#define TEST_BUFFER_SIZE 8u // EEPROM Àбâ/¾²±â ¹öÆÛ »çÀÌÁî +#define EEPROM_ADDR 0x50u // AT24C08CÀÇ ±âº» I2C ÁÖ¼Ò, A2, A1, A0 ¸ðµÎ 0ÀÏ °æ¿ì + + +#endif // DEFINE_H + + + diff --git a/src/eeprom.c b/src/eeprom.c new file mode 100644 index 0000000..8dff95a --- /dev/null +++ b/src/eeprom.c @@ -0,0 +1,200 @@ +#include "eeprom.h" +#include "ctrl_module.h" +#include "sleep.h" + +u8 g_szIpInfo[IPINFO_SIZE] = { 0, }; // IP Address, Port + +// EEPROM ÃʱâÈ­ +void InitEeprom(void) +{ + XIicPs_Config *ConfigPtr; + s32_t Status; + u32_t nData; + u32_t nRet; + u8 cEepromBuf[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + xil_printf("InitEeprom Start\n"); + + ConfigPtr = XIicPs_LookupConfig(XPAR_XIICPS_0_DEVICE_ID); + if (NULL == ConfigPtr) + { +#if DEBUG_COVER + xil_printf("No config found for %d\n", XPAR_XIICPS_0_DEVICE_ID); +#endif + } + else + { + Status = XIicPs_CfgInitialize(&Iic, ConfigPtr, ConfigPtr->BaseAddress); + if (Status != XST_SUCCESS) + { +#if DEBUG_COVER + xil_printf("Initialization failed\n"); +#endif + } + else + { + (void)XIicPs_SetSClk(&Iic, IIC_SCLK_RATE); + + LoadEepromInfo(cEepromBuf); // Eeprom Á¤º¸ Àüü Àбâ + + if(cEepromBuf[1] == 0xFFu) // °øÀåÃʱâÈ­°ªÀ̸é 0 ¼³Á¤ + { + g_cDeviceErase = 0u; + } + else // Á¤»ó°ªÀ̸é 0 ¶Ç´Â 1 + { +#if DEBUG_COVER + g_cDeviceErase = cEepromBuf[1]; +#endif + } + xil_printf("Init Eeprom g_cDeviceErase:%d\n\n", (u32_t)g_cDeviceErase); + + nData = cEepromBuf[2]; + g_nEncoderMT = nData << 16; + nData = cEepromBuf[3]; + g_nEncoderMT += nData << 8; + g_nEncoderMT += cEepromBuf[4]; + + xil_printf("Init Eeprom g_nEncoderMT:%06X\n", g_nEncoderMT); + + xil_printf("InitEeprom End\n"); + } + } +} + + +static s32 EepromWriteByte(XIicPs *IicInstance, u8 Address, u8 Data) +{ + s32_t Status, nRet = XST_SUCCESS; + u8 Buffer[2]; + + Buffer[0] = Address; // 1¹ÙÀÌÆ® ÁÖ¼Ò // ÁÖ¼Ò ¹× µ¥ÀÌÅÍ ¹öÆÛ ¼³Á¤ + Buffer[1] = Data; // µ¥ÀÌÅÍ + + Status = XIicPs_MasterSendPolled(IicInstance, Buffer, 2, EEPROM_ADDR); // I2C¸¦ ÅëÇÑ µ¥ÀÌÅÍ ¾²±â + if (Status != XST_SUCCESS) + { +#if DEBUG_COVER + nRet = Status; +#endif + } + else + { + while (XIicPs_BusIsBusy(IicInstance) == 1) + { + ; // I2C Æ®·£Àè¼ÇÀÌ ¿Ï·áµÉ ¶§±îÁö ´ë±â + } + + (void)usleep(10000); // ¾²±â Áö¿¬ ´ë±â (ÃÖ´ë 10ms, EEPROM µ¥ÀÌÅÍ ½ÃÆ® ÂüÁ¶) + } + + return nRet; +} + + +static s32 EepromReadByte(XIicPs *IicInstance, u8 Address, u8 *Data) +{ + s32_t Status, nRet = XST_SUCCESS; + + + Status = XIicPs_MasterSendPolled(IicInstance, &Address, 1, EEPROM_ADDR); // ÁÖ¼Ò Àü¼Û + if (Status != XST_SUCCESS) + { +#if DEBUG_COVER + nRet = Status; +#endif + } + else + { + while (XIicPs_BusIsBusy(IicInstance) == 1) + { + ; // I2C Æ®·£Àè¼ÇÀÌ ¿Ï·áµÉ ¶§±îÁö ´ë±â + } + + Status = XIicPs_MasterRecvPolled(IicInstance, Data, 1, EEPROM_ADDR); // µ¥ÀÌÅÍ Àбâ + if (Status != XST_SUCCESS) + { +#if DEBUG_COVER + nRet = Status; +#endif + } + } + + return nRet; +} + +// ¿£ÄÚ´õ ¸ÖƼÅÏ°ª ¾²±â +void SaveEncoderMT(u32 cVal) +{ + s32 Status = 0; + u8 cAddr = 0x02; + + Status = EepromWriteByte(&Iic, cAddr, (u8_t)(cVal >> 16)); // bit23 ~ 16 ±â·Ï // EEPROM¿¡ µ¥ÀÌÅÍ ¾²±â + if (Status != XST_SUCCESS) + { +#if DEBUG_COVER + xil_printf("EEPROM write failed\n"); +#endif + } + else + { + xil_printf("encoder multiturn 1st write succeded:%X\n", (u32_t)(cVal >> 16)); + } + + (void)usleep(10000); + + Status = EepromWriteByte(&Iic, (u8_t)(cAddr + 1u), (u8_t)(cVal >> 8)); // bit15 ~ 8 ±â·Ï // EEPROM¿¡ µ¥ÀÌÅÍ ¾²±â + if (Status != XST_SUCCESS) + { +#if DEBUG_COVER + xil_printf("EEPROM write failed\n"); +#endif + } + else + { + xil_printf("encoder multiturn 2nd write succeded:%X\n", (u32_t)(cVal >> 8)); + } + + (void)usleep(10000); + + Status = EepromWriteByte(&Iic, (u8_t)(cAddr + 2u), (u8_t)cVal); // bit7 ~ 0 ±â·Ï + if (Status != XST_SUCCESS) + { +#if DEBUG_COVER + xil_printf("EEPROM write failed\n"); +#endif + } + else + { + xil_printf("encoder multiturn 3rd write succeded:%X\n", (u32_t)cVal); + } + + return Status; +} + +// Eeprom Á¤º¸ Àüü Àбâ +// Eeprom Read ½Ã Address Á¦¾î°¡ ÁöÁ¤´ë·Î µ¿ÀÛµÇÁö ¾Ê´Â °æ¿ì +// ¹ß»ýÇÏ¿© ÀÏÁ¤ ¹üÀ§ Àо ó¸®Çϵµ·Ï º¯°æÇÔ +static void LoadEepromInfo(u8* cVal) +{ + u8 i = 1u; // Start Address + s32_t Status; + u8 cData = 0u; + + for(i = 0u; i < 5u; i++) + { + Status = EepromReadByte(&Iic, i, &cData); + if (Status != XST_SUCCESS) + { +#if DEBUG_COVER + xil_printf("EEPROM read failed\n"); +#endif + } + else + { + xil_printf("read addr:%d, cData:%X\r\n", (u32_t)i, (u32_t)cData); + } + cVal[i] = cData; // °ª °¡Á®°¡±â + } +} + diff --git a/src/eeprom.h b/src/eeprom.h new file mode 100644 index 0000000..f9bddc5 --- /dev/null +++ b/src/eeprom.h @@ -0,0 +1,19 @@ +#ifndef EEPROM_H +#define EEPROM_H + +#include "xiicps.h" +#include "define.h" + +extern u8 g_szIpInfo[IPINFO_SIZE]; // IP Address, Port + +XIicPs Iic; // I2C ÀνºÅϽº + + +void InitEeprom(void); // EEPROM ÃʱâÈ­ +static s32 EepromWriteByte(XIicPs *IicInstance, u8 Address, u8 Data); +static s32 EepromReadByte(XIicPs *IicInstance, u8 Address, u8 *Data); + +void SaveEncoderMT(u32 cVal); // ¿£ÄÚ´õ ¸ÖƼÅÏ°ª ¾²±â +static void LoadEepromInfo(u8* cVal); // Eeprom Á¤º¸ Àüü Àбâ + +#endif diff --git a/src/lscript.ld b/src/lscript.ld new file mode 100644 index 0000000..1ac4087 --- /dev/null +++ b/src/lscript.ld @@ -0,0 +1,289 @@ +/*******************************************************************/ +/* */ +/* This file is automatically generated by linker script generator.*/ +/* */ +/* Version: 2019.2 */ +/* */ +/* Copyright (c) 2010-2019 Xilinx, Inc. All rights reserved. */ +/* */ +/* Description : Cortex-A9 Linker Script */ +/* */ +/*******************************************************************/ + +_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0xA000; +_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0xA000; + +_ABORT_STACK_SIZE = DEFINED(_ABORT_STACK_SIZE) ? _ABORT_STACK_SIZE : 1024; +_SUPERVISOR_STACK_SIZE = DEFINED(_SUPERVISOR_STACK_SIZE) ? _SUPERVISOR_STACK_SIZE : 2048; +_IRQ_STACK_SIZE = DEFINED(_IRQ_STACK_SIZE) ? _IRQ_STACK_SIZE : 1024; +_FIQ_STACK_SIZE = DEFINED(_FIQ_STACK_SIZE) ? _FIQ_STACK_SIZE : 1024; +_UNDEF_STACK_SIZE = DEFINED(_UNDEF_STACK_SIZE) ? _UNDEF_STACK_SIZE : 1024; + +/* Define Memories in the system */ + +MEMORY +{ + axi_bram_ctrl_0_Mem0 : ORIGIN = 0x40000000, LENGTH = 0x2000 + ps7_ddr_0 : ORIGIN = 0x100000, LENGTH = 0x1FF00000 + ps7_qspi_linear_0 : ORIGIN = 0xFC000000, LENGTH = 0x1000000 + ps7_ram_0 : ORIGIN = 0x0, LENGTH = 0x30000 + ps7_ram_1 : ORIGIN = 0xFFFF0000, LENGTH = 0xFE00 +} + +/* Specify the default entry point to the program */ + +ENTRY(_vector_table) + +/* Define the sections, and where they are mapped in memory */ + +SECTIONS +{ +.text : { + KEEP (*(.vectors)) + *(.boot) + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + *(.plt) + *(.gnu_warning) + *(.gcc_execpt_table) + *(.glue_7) + *(.glue_7t) + *(.vfp11_veneer) + *(.ARM.extab) + *(.gnu.linkonce.armextab.*) +} > ps7_ddr_0 + +.init : { + KEEP (*(.init)) +} > ps7_ddr_0 + +.fini : { + KEEP (*(.fini)) +} > ps7_ddr_0 + +.rodata : { + __rodata_start = .; + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + __rodata_end = .; +} > ps7_ddr_0 + +.rodata1 : { + __rodata1_start = .; + *(.rodata1) + *(.rodata1.*) + __rodata1_end = .; +} > ps7_ddr_0 + +.sdata2 : { + __sdata2_start = .; + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + __sdata2_end = .; +} > ps7_ddr_0 + +.sbss2 : { + __sbss2_start = .; + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + __sbss2_end = .; +} > ps7_ddr_0 + +.data : { + __data_start = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + *(.jcr) + *(.got) + *(.got.plt) + __data_end = .; +} > ps7_ddr_0 + +.data1 : { + __data1_start = .; + *(.data1) + *(.data1.*) + __data1_end = .; +} > ps7_ddr_0 + +.got : { + *(.got) +} > ps7_ddr_0 + +.ctors : { + __CTOR_LIST__ = .; + ___CTORS_LIST___ = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __CTOR_END__ = .; + ___CTORS_END___ = .; +} > ps7_ddr_0 + +.dtors : { + __DTOR_LIST__ = .; + ___DTORS_LIST___ = .; + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + __DTOR_END__ = .; + ___DTORS_END___ = .; +} > ps7_ddr_0 + +.fixup : { + __fixup_start = .; + *(.fixup) + __fixup_end = .; +} > ps7_ddr_0 + +.eh_frame : { + *(.eh_frame) +} > ps7_ddr_0 + +.eh_framehdr : { + __eh_framehdr_start = .; + *(.eh_framehdr) + __eh_framehdr_end = .; +} > ps7_ddr_0 + +.gcc_except_table : { + *(.gcc_except_table) +} > ps7_ddr_0 + +.mmu_tbl (ALIGN(16384)) : { + __mmu_tbl_start = .; + *(.mmu_tbl) + __mmu_tbl_end = .; +} > ps7_ddr_0 + +.ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + *(.gnu.linkonce.armexidix.*.*) + __exidx_end = .; +} > ps7_ddr_0 + +.preinit_array : { + __preinit_array_start = .; + KEEP (*(SORT(.preinit_array.*))) + KEEP (*(.preinit_array)) + __preinit_array_end = .; +} > ps7_ddr_0 + +.init_array : { + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; +} > ps7_ddr_0 + +.fini_array : { + __fini_array_start = .; + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array)) + __fini_array_end = .; +} > ps7_ddr_0 + +.ARM.attributes : { + __ARM.attributes_start = .; + *(.ARM.attributes) + __ARM.attributes_end = .; +} > ps7_ddr_0 + +.sdata : { + __sdata_start = .; + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + __sdata_end = .; +} > ps7_ddr_0 + +.sbss (NOLOAD) : { + __sbss_start = .; + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + __sbss_end = .; +} > ps7_ddr_0 + +.tdata : { + __tdata_start = .; + *(.tdata) + *(.tdata.*) + *(.gnu.linkonce.td.*) + __tdata_end = .; +} > ps7_ddr_0 + +.tbss : { + __tbss_start = .; + *(.tbss) + *(.tbss.*) + *(.gnu.linkonce.tb.*) + __tbss_end = .; +} > ps7_ddr_0 + +.bss (NOLOAD) : { + __bss_start = .; + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + __bss_end = .; +} > ps7_ddr_0 + +_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 ); + +_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 ); + +/* Generate Stack and Heap definitions */ + +.heap (NOLOAD) : { + . = ALIGN(16); + _heap = .; + HeapBase = .; + _heap_start = .; + . += _HEAP_SIZE; + _heap_end = .; + HeapLimit = .; +} > ps7_ddr_0 + +.stack (NOLOAD) : { + . = ALIGN(16); + _stack_end = .; + . += _STACK_SIZE; + . = ALIGN(16); + _stack = .; + __stack = _stack; + . = ALIGN(16); + _irq_stack_end = .; + . += _IRQ_STACK_SIZE; + . = ALIGN(16); + __irq_stack = .; + _supervisor_stack_end = .; + . += _SUPERVISOR_STACK_SIZE; + . = ALIGN(16); + __supervisor_stack = .; + _abort_stack_end = .; + . += _ABORT_STACK_SIZE; + . = ALIGN(16); + __abort_stack = .; + _fiq_stack_end = .; + . += _FIQ_STACK_SIZE; + . = ALIGN(16); + __fiq_stack = .; + _undef_stack_end = .; + . += _UNDEF_STACK_SIZE; + . = ALIGN(16); + __undef_stack = .; +} > ps7_ddr_0 + +_end = .; +} + diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..e721a25 --- /dev/null +++ b/src/main.c @@ -0,0 +1,277 @@ +#include "xparameters.h" +#include "netif/xadapter.h" +#include "platform.h" +#include "platform_config.h" +#include "lwipopts.h" +#include "xil_printf.h" +#include "sleep.h" +#include "lwip/priv/tcp_priv.h" +#include "lwip/init.h" +#include "lwip/inet.h" +#include "lwip/tcp.h" +#include "xil_cache.h" + +#include "define.h" +#include "main.h" +#include "ctrl_module.h" +#include "tcpipcomm.h" +#include "tcp_client.h" +#include "udp_client.h" +#include "eeprom.h" + +#if LWIP_IPV6==1 +#include "lwip/ip6_addr.h" +#include "lwip/ip6.h" +#else + +#if LWIP_DHCP==1 +#include "lwip/dhcp.h" +extern volatile u32_t dhcp_timoutcntr; +#endif +#define DEFAULT_IP_ADDRESS "172.16.0.50" +#define DEFAULT_IP_MASK "255.255.255.0" +#define DEFAULT_GW_ADDRESS "172.16.0.1" +#endif /* LWIP_IPV6 */ + +extern volatile u32_t TcpFastTmrFlag; +extern volatile u32_t TcpSlowTmrFlag; + +struct netif server_netif; + +#if defined (__arm__) && !defined (ARMR5) +#if XPAR_GIGE_PCS_PMA_SGMII_CORE_PRESENT == 1 || \ + XPAR_GIGE_PCS_PMA_1000BASEX_CORE_PRESENT == 1 +u32_t ProgramSi5324(void); +u32_t ProgramSfpPhy(void); +#endif +#endif + +#ifdef XPS_BOARD_ZCU102 +#ifdef XPAR_XIICPS_0_DEVICE_ID +u32_t IicPhyReset(void); +#endif +#endif + + +#if LWIP_IPV6==1 +static void print_ipv6(u32_t *msg, ip_addr_t *ip) +{ + print(msg); + xil_printf(" %s\n\r", inet6_ntoa(*ip)); +} +#else +static void print_ip(const char8 *msg, const ip_addr_t *ip) +{ + print(msg); + xil_printf("%d.%d.%d.%d\r\n", (u32_t)ip4_addr1(ip), (u32_t)ip4_addr2(ip), + (u32_t)ip4_addr3(ip), (u32_t)ip4_addr4(ip)); +} + +static void print_ip_settings(const ip_addr_t *ip, const ip_addr_t *mask, const ip_addr_t *gw) +{ + print_ip("Board IP: ", ip); + print_ip("Netmask : ", mask); + print_ip("Gateway : ", gw); +} + +static void assign_default_ip(const ip_addr_t *ip, const ip_addr_t *mask, const ip_addr_t *gw) +{ + u32_t err; + + xil_printf("Configuring default IP %s \r\n", DEFAULT_IP_ADDRESS); + + err = (u32_t)inet_aton(DEFAULT_IP_ADDRESS, ip); + if (err == 0u) + { +#if DEBUG_COVER + xil_printf("Invalid default IP address: %d\r\n", (u32_t)err); +#endif + } + + err = (u32_t)inet_aton(DEFAULT_IP_MASK, mask); + if (err == 0u) + { +#if DEBUG_COVER + xil_printf("Invalid default IP MASK: %d\r\n", (u32_t)err); +#endif + } + + err = (u32_t)inet_aton(DEFAULT_GW_ADDRESS, gw); + if (err == 0u) + { +#if DEBUG_COVER + xil_printf("Invalid default gateway address: %d\r\n", (u32_t)err); +#endif + } +} +#endif /* LWIP_IPV6 */ + + +static void MakeTiming(void) +{ + + if(++g_nCnt1 > TIMER_BASE) + { + g_nCnt1 = 0; + g_nCnt2++; // ctrl_module.c CtrlModuleProcess() + g_nEcdeepromCnt++; // ctrl_module.c SetMotor() + g_nTcpCliConCnt++; // tcp_client.c ConnectToTcpServer() + g_nReportCnt++; // udp_client.c UdpCommPeriod() + + if(g_stTcpClientMy.cConnected == TRUE) // client°¡ ÀÓ¹«Ã³¸® S/W(Server)¿¡ ¿¬°áµÈ »óÅ¿¡¼­¸¸ Ä«¿îÅÍ + { + g_nBitDetailHBCnt++; // udp_client.c UdpCommProcess() + g_nTcpDisconnectCnt++; // udp_client.c + } + } +} + +static void TcpipProcChk(struct netif* nif) +{ + if (TcpFastTmrFlag != 0u) { + tcp_fasttmr(); + TcpFastTmrFlag = 0u; + } + if (TcpSlowTmrFlag != 0u) { + tcp_slowtmr(); + TcpSlowTmrFlag = 0u; + } + (void)xemacif_input(nif); +} + +u32_t main(void) +{ + struct netif *netif; + u8_t mac_ethernet_address[] = { 0x48, 0x21, 0x0B, 0x5A, 0x37, 0xA7 }; /* the mac address of the board. this should be unique per board */ + u16_t nData = 0; + u32_t nData32 = 0; + + netif = &server_netif; + + static ip_addr_t ipaddr, netmask, gw; + +#if defined (__arm__) && !defined (ARMR5) +#if XPAR_GIGE_PCS_PMA_SGMII_CORE_PRESENT == 1 || \ + XPAR_GIGE_PCS_PMA_1000BASEX_CORE_PRESENT == 1 + ProgramSi5324(); + ProgramSfpPhy(); +#endif +#endif + + /* Define this board specific macro in order perform PHY reset + * on ZCU102 + */ +#ifdef XPS_BOARD_ZCU102 + IicPhyReset(); +#endif + + init_platform(); + + xil_printf("\r\n\r\n"); + xil_printf("=====================================================\n\r"); + xil_printf("-----\tAntMastPh2 Control Module V%d.%d.%d.%d\t-----\n\r", (u32_t)VER_VERSION, (u32_t)VER_UPDATE, (u32_t)VER_TEST, (u32_t)VER_COMPILE); + +#if TEST_LOG_ON + xil_printf("-----\tCompiled by HKC\t[Debug]\t\t\t-----\n\r"); +#else + xil_printf("-----\tCompiled by HKC\t[Release]\t\t-----\n\r"); +#endif + xil_printf("=====================================================\n\r"); + + g_szIpInfo[0] = MY_IP_ADDR1; + g_szIpInfo[1] = MY_IP_ADDR2; + g_szIpInfo[2] = MY_IP_ADDR3; + g_szIpInfo[3] = MY_IP_ADDR4; + + IP4_ADDR(&ipaddr, g_szIpInfo[0], g_szIpInfo[1], g_szIpInfo[2], g_szIpInfo[3]); + IP4_ADDR(&netmask, 255, 255, 255, 0); // 24.06.27 º¯°æ + IP4_ADDR(&gw, g_szIpInfo[0], g_szIpInfo[1], g_szIpInfo[2], 1); // 24.06.27 º¯°æ + + lwip_init(); /* initialize lwIP */ + + //if (!xemac_add(netif, NULL, NULL, NULL, mac_ethernet_address, + /* Add network interface to the netif_list, and set it as default */ + if (!xemac_add((struct netif*)netif, (ip_addr_t*)&ipaddr, (ip_addr_t*)&netmask, (ip_addr_t*)&gw, (u8_t*)mac_ethernet_address, (u32_t)PLATFORM_EMAC_BASEADDR)) + { +#if DEBUG_COVER + xil_printf("Error adding N/W interface\r\n"); +#endif + } + else + { +#if LWIP_IPV6==1 + netif->ip6_autoconfig_enabled = 1; + netif_create_ip6_linklocal_address(netif, 1); + netif_ip6_addr_set_state(netif, 0, IP6_ADDR_VALID); + print_ipv6("\n\rlink local IPv6 address is:", &netif->ip6_addr[0]); +#endif /* LWIP_IPV6 */ + + netif_set_default(netif); + + /* now enable interrupts */ + platform_enable_interrupts(); + + /* specify that the network if is up */ + netif_set_up(netif); + +#if (LWIP_IPV6==0) +#if (LWIP_DHCP==1) + /* Create a new DHCP client for this interface. + * Note: you must call dhcp_fine_tmr() and dhcp_coarse_tmr() at + * the predefined regular intervals after starting the client. + */ + dhcp_start(netif); + dhcp_timoutcntr = 24; + while (((netif->ip_addr.addr) == 0) && (dhcp_timoutcntr > 0)) + xemacif_input(netif); + + if (dhcp_timoutcntr <= 0) { + if ((netif->ip_addr.addr) == 0) { + xil_printf("ERROR: DHCP request timed out\r\n"); + assign_default_ip(&(netif->ip_addr), &(netif->netmask), &(netif->gw)); + } + } + + /* print IP address, netmask and gateway */ +#else + assign_default_ip((const ip_addr_t*)&(netif->ip_addr), (const ip_addr_t*)&(netif->netmask), (const ip_addr_t*)&(netif->gw)); +#endif + print_ip_settings((const ip_addr_t*)&(netif->ip_addr), (const ip_addr_t*)&(netif->netmask), (const ip_addr_t*)&(netif->gw)); +#endif /* LWIP_IPV6 */ + + g_cSn = 0; // ÀÀ´äÆÐŶ ¼Û½Å Ä«¿îÅÍ + + InitEeprom(); // eeprom ÃʱâÈ­ + InitCtrlModule(); // Á¦¾îºÎ ¸ðµâ Ãʱ⠼³Á¤ //InitTcpServer(); // TCP ¼­¹ö ÃʱâÈ­ + + InitTcpClient(); // TCP Client ÃʱâÈ­ + InitUdpServer(); // UDP Server ÃʱâÈ­ //InitUdpClient(); // UDP Client ÃʱâÈ­ + + InitCompareMember(); // ¹®ÀÚ¿­ ºñ±³ ÃʱâÈ­ + while (1) + { + if(g_cDeviceErase == 0u) // Device Erase°¡ ¼³Á¤µÇÁö ¾ÊÀ¸¸é Á¤»ó µ¿ÀÛ, Àû¿ëÇϸé Àüü ¿À·ù¹ß»ý 24.03.05 + { + MakeTiming(); + + CtrlModuleProcess(); // Á¦¾îºÎ ¸ðµâ µ¿ÀÛ Ã³¸® //TcpServCommProcess(); // ¼­¹ö¿¡ ¿¬°áµÈ TCP Ŭ¶óÀ̾ðÆ® ¼ö½Å ¹× ¼Û½Å ó¸® + + TcpClientCommProceess(); // TCP Client ¼ö½Å ¹× ¼Û½Å ó¸® + ConnectToTcpServer(); // TCP ¼­¹ö ¹Ýº¹ Á¢¼Ó °ü¸® + UdpCommProcess(); // UDP Åë½Å ó¸® + + TcpipProcChk(netif); + + } + } + } + + return 0; +} + + + + + + + diff --git a/src/main.h b/src/main.h new file mode 100644 index 0000000..650b426 --- /dev/null +++ b/src/main.h @@ -0,0 +1,17 @@ +#ifndef MAIN_H +#define MAIN_H + +#include "xtime_l.h" +#include "tcp_client.h" + + +static XTime g_nStartTime; +static XTime g_nCurTime; + +static uint32_t g_nCnt1; + + +static void MakeTiming(void); +static void TcpipProcChk(struct netif* nif); + +#endif // MAIN_H diff --git a/src/platform.c b/src/platform.c new file mode 100644 index 0000000..0a886d6 --- /dev/null +++ b/src/platform.c @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2009 - 2019 Xilinx, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + */ +#if __MICROBLAZE__ +#include "arch/cc.h" +#include "platform.h" +#include "platform_config.h" +#include "xil_cache.h" +#include "xparameters.h" +#include "xintc.h" +#include "xil_exception.h" +#include "lwip/tcp.h" +#ifdef STDOUT_IS_16550 +#include "xuartns550_l.h" +#endif + +#include "lwip/tcp.h" + +#if LWIP_DHCP==1 +volatile int dhcp_timoutcntr = 24; +void dhcp_fine_tmr(); +void dhcp_coarse_tmr(); +#endif + +volatile int TcpFastTmrFlag = 0; +volatile int TcpSlowTmrFlag = 0; + +volatile u64_t tickcntr = 0; +void +timer_callback() +{ + /* we need to call tcp_fasttmr & tcp_slowtmr at intervals specified + * by lwIP. + * It is not important that the timing is absoluetly accurate. + */ + static int odd = 1; +#if LWIP_DHCP==1 + static int dhcp_timer = 0; +#endif + tickcntr++; + if(tickcntr % 25 == 0){ + TcpFastTmrFlag = 1; + + odd = !odd; + if (odd) { + TcpSlowTmrFlag = 1; +#if LWIP_DHCP==1 + dhcp_timer++; + dhcp_timoutcntr--; + dhcp_fine_tmr(); + if (dhcp_timer >= 120) { + dhcp_coarse_tmr(); + dhcp_timer = 0; + } +#endif + } + } +} + +static XIntc intc; + +void platform_setup_interrupts() +{ + XIntc *intcp; + intcp = &intc; + + XIntc_Initialize(intcp, XPAR_INTC_0_DEVICE_ID); + XIntc_Start(intcp, XIN_REAL_MODE); + + /* Start the interrupt controller */ + XIntc_MasterEnable(XPAR_INTC_0_BASEADDR); + +#ifdef __MICROBLAZE__ + microblaze_register_handler((XInterruptHandler)XIntc_InterruptHandler, intcp); +#endif + + platform_setup_timer(); + +#ifdef XPAR_ETHERNET_MAC_IP2INTC_IRPT_MASK + /* Enable timer and EMAC interrupts in the interrupt controller */ + XIntc_EnableIntr(XPAR_INTC_0_BASEADDR, +#ifdef __MICROBLAZE__ + PLATFORM_TIMER_INTERRUPT_MASK | +#endif + XPAR_ETHERNET_MAC_IP2INTC_IRPT_MASK); +#endif + + +#ifdef XPAR_INTC_0_LLTEMAC_0_VEC_ID +#ifdef __MICROBLAZE__ + XIntc_Enable(intcp, PLATFORM_TIMER_INTERRUPT_INTR); +#endif + XIntc_Enable(intcp, XPAR_INTC_0_LLTEMAC_0_VEC_ID); +#endif + + +#ifdef XPAR_INTC_0_AXIETHERNET_0_VEC_ID + XIntc_Enable(intcp, PLATFORM_TIMER_INTERRUPT_INTR); + XIntc_Enable(intcp, XPAR_INTC_0_AXIETHERNET_0_VEC_ID); +#endif + + +#ifdef XPAR_INTC_0_EMACLITE_0_VEC_ID +#ifdef __MICROBLAZE__ + XIntc_Enable(intcp, PLATFORM_TIMER_INTERRUPT_INTR); +#endif + XIntc_Enable(intcp, XPAR_INTC_0_EMACLITE_0_VEC_ID); +#endif + + +} + +void +enable_caches() +{ +#ifdef __MICROBLAZE__ +#ifdef XPAR_MICROBLAZE_USE_ICACHE + Xil_ICacheEnable(); +#endif +#ifdef XPAR_MICROBLAZE_USE_DCACHE + Xil_DCacheEnable(); +#endif +#endif +} + +void +disable_caches() +{ + Xil_DCacheDisable(); + Xil_ICacheDisable(); +} + +void init_platform() +{ + enable_caches(); + +#ifdef STDOUT_IS_16550 + XUartNs550_SetBaud(STDOUT_BASEADDR, XPAR_XUARTNS550_CLOCK_HZ, 9600); + XUartNs550_SetLineControlReg(STDOUT_BASEADDR, XUN_LCR_8_DATA_BITS); +#endif + + platform_setup_interrupts(); +} + +void cleanup_platform() +{ + disable_caches(); +} + +u64_t get_time_ms() +{ + return tickcntr * 10; +} + +#endif diff --git a/src/platform.h b/src/platform.h new file mode 100644 index 0000000..010b34c --- /dev/null +++ b/src/platform.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2009 - 2019 Xilinx, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + */ + +#ifndef __PLATFORM_H_ +#define __PLATFORM_H_ + +void init_platform(); +void cleanup_platform(); +#ifdef __MICROBLAZE__ +void timer_callback(); +#endif +void platform_setup_timer(); +void platform_enable_interrupts(); +u64_t get_time_ms(); +#endif diff --git a/src/platform_config.h b/src/platform_config.h new file mode 100644 index 0000000..e515d30 --- /dev/null +++ b/src/platform_config.h @@ -0,0 +1,10 @@ +#ifndef __PLATFORM_CONFIG_H_ +#define __PLATFORM_CONFIG_H_ + + +#define PLATFORM_EMAC_BASEADDR XPAR_XEMACPS_0_BASEADDR + +#define PLATFORM_ZYNQ + + +#endif diff --git a/src/platform_zynq.c b/src/platform_zynq.c new file mode 100644 index 0000000..e7d6942 --- /dev/null +++ b/src/platform_zynq.c @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2010 - 2019 Xilinx, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + */ +/* +* platform_zynq.c +* +* Zynq platform specific functions. +* +* 02/29/2012: UART initialization is removed. Timer initializations are +* removed. All unnecessary include files and hash defines are removed. +* 03/01/2013: Timer initialization is added back. Support for SI #692601 is +* added in the timer callback. The SI #692601 refers to the following issue. +* +* The EmacPs has a HW bug on the Rx path for heavy Rx traffic. +* Under heavy Rx traffic because of the HW bug there are times when the Rx path +* becomes unresponsive. The workaround for it is to check for the Rx path for +* traffic (by reading the stats registers regularly). If the stats register +* does not increment for sometime (proving no Rx traffic), the function resets +* the Rx data path. +* +* + */ + +#ifdef __arm__ + +#include "platform_config.h" +#ifdef PLATFORM_ZYNQ +#include "xparameters.h" +#include "xparameters_ps.h" /* defines XPAR values */ +#include "xil_cache.h" +#include "xscugic.h" +#include "lwip/tcp.h" +#include "xil_printf.h" +#include "netif/xadapter.h" +#include "xscutimer.h" +#include "xtime_l.h" + +#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID +#define TIMER_DEVICE_ID XPAR_SCUTIMER_DEVICE_ID +#define INTC_BASE_ADDR XPAR_SCUGIC_0_CPU_BASEADDR +#define INTC_DIST_BASE_ADDR XPAR_SCUGIC_0_DIST_BASEADDR +#define TIMER_IRPT_INTR XPAR_SCUTIMER_INTR + +#define RESET_RX_CNTR_LIMIT 400 + +void tcp_fasttmr(void); +void tcp_slowtmr(void); + +static XScuTimer TimerInstance; + +#ifndef USE_SOFTETH_ON_ZYNQ +static int ResetRxCntr = 0; +extern struct netif server_netif; +#endif + +volatile int TcpFastTmrFlag = 0; +volatile int TcpSlowTmrFlag = 0; + +#if LWIP_DHCP==1 +volatile int dhcp_timoutcntr = 24; +void dhcp_fine_tmr(); +void dhcp_coarse_tmr(); +#endif + +void +timer_callback(XScuTimer * TimerInstance) +{ + /* we need to call tcp_fasttmr & tcp_slowtmr at intervals specified + * by lwIP. It is not important that the timing is absoluetly accurate. + */ + static int odd = 1; +#if LWIP_DHCP==1 + static int dhcp_timer = 0; +#endif + TcpFastTmrFlag = 1; + + odd = !odd; +#ifndef USE_SOFTETH_ON_ZYNQ + ResetRxCntr++; +#endif + if (odd) { + TcpSlowTmrFlag = 1; +#if LWIP_DHCP==1 + dhcp_timer++; + dhcp_timoutcntr--; + dhcp_fine_tmr(); + if (dhcp_timer >= 120) { + dhcp_coarse_tmr(); + dhcp_timer = 0; + } +#endif + } + + /* For providing an SW alternative for the SI #692601. Under heavy + * Rx traffic if at some point the Rx path becomes unresponsive, the + * following API call will ensures a SW reset of the Rx path. The + * API xemacpsif_resetrx_on_no_rxdata is called every 100 milliseconds. + * This ensures that if the above HW bug is hit, in the worst case, + * the Rx path cannot become unresponsive for more than 100 + * milliseconds. + */ +#ifndef USE_SOFTETH_ON_ZYNQ + if (ResetRxCntr >= RESET_RX_CNTR_LIMIT) { + xemacpsif_resetrx_on_no_rxdata(&server_netif); + ResetRxCntr = 0; + } +#endif + XScuTimer_ClearInterruptStatus(TimerInstance); +} + +void platform_setup_timer(void) +{ + int Status = XST_SUCCESS; + XScuTimer_Config *ConfigPtr; + int TimerLoadValue = 0; + + ConfigPtr = XScuTimer_LookupConfig(TIMER_DEVICE_ID); + Status = XScuTimer_CfgInitialize(&TimerInstance, ConfigPtr, + ConfigPtr->BaseAddr); + if (Status != XST_SUCCESS) { + + xil_printf("In %s: Scutimer Cfg initialization failed...\r\n", + __func__); + return; + } + + Status = XScuTimer_SelfTest(&TimerInstance); + if (Status != XST_SUCCESS) { + xil_printf("In %s: Scutimer Self test failed...\r\n", + __func__); + return; + + } + + XScuTimer_EnableAutoReload(&TimerInstance); + /* + * Set for 250 milli seconds timeout. + */ + TimerLoadValue = XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ / 8; + + XScuTimer_LoadTimer(&TimerInstance, TimerLoadValue); + return; +} + +void platform_setup_interrupts(void) +{ + Xil_ExceptionInit(); + + XScuGic_DeviceInitialize(INTC_DEVICE_ID); + + /* + * Connect the interrupt controller interrupt handler to the hardware + * interrupt handling logic in the processor. + */ + Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT, + (Xil_ExceptionHandler)XScuGic_DeviceInterruptHandler, + (void *)INTC_DEVICE_ID); + /* + * Connect the device driver handler that will be called when an + * interrupt for the device occurs, the handler defined above performs + * the specific interrupt processing for the device. + */ + XScuGic_RegisterHandler(INTC_BASE_ADDR, TIMER_IRPT_INTR, + (Xil_ExceptionHandler)timer_callback, + (void *)&TimerInstance); + /* + * Enable the interrupt for scu timer. + */ + XScuGic_EnableIntr(INTC_DIST_BASE_ADDR, TIMER_IRPT_INTR); + + return; +} + +void platform_enable_interrupts() +{ + /* + * Enable non-critical exceptions. + */ + Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ); + XScuTimer_EnableInterrupt(&TimerInstance); + XScuTimer_Start(&TimerInstance); + return; +} + +void init_platform() +{ + platform_setup_timer(); + platform_setup_interrupts(); + + return; +} + +void cleanup_platform() +{ + Xil_ICacheDisable(); + Xil_DCacheDisable(); + return; +} + +u64_t get_time_ms() +{ +#define COUNTS_PER_MILLI_SECOND (COUNTS_PER_SECOND/1000) + XTime tCur = 0; + XTime_GetTime(&tCur); + return (tCur/COUNTS_PER_MILLI_SECOND); +} + +#endif +#endif diff --git a/src/tcp_client.c b/src/tcp_client.c new file mode 100644 index 0000000..c166857 --- /dev/null +++ b/src/tcp_client.c @@ -0,0 +1,288 @@ +#include "tcp_client.h" + +// TCP Client ÃʱâÈ­ +void InitTcpClient(void) +{ + IP_ADDR4(&g_ipaddrMP, TCP_MP_IP_ADDR1, TCP_MP_IP_ADDR2, TCP_MP_IP_ADDR3, TCP_MP_IP_ADDR4); // ÀÓ¹« IP + + g_stTcpClientMy.cConnected = FALSE; + (void)memset((void *)g_stTcpClientMy.szRecvData, (s32_t)0, (s32_t)(NUM_RECV_BUF * sizeof(u8_t))); + g_stTcpClientMy.nRecvLen = 0; + g_stTcpClientMy.cRecvFlag = FALSE; + g_stTcpClientMy.cIsConnecting = FALSE; + + m_nConnectCnt = 0; + g_nTcpDisconnectChk = 1u; // Á¢¼Ó ÈÄ ÀÓ¹«Ã³¸®S/WÀÇ Heart Beat ¹Ì ¼ö½ÅÀÌ 5ÃÊ ÀÌ»ó À¯ÁöµÇ¸é Á¢¼ÓÇØÁ¦ + + tcp_client_connect(); // TCP ¼­¹ö Á¢¼Ó +} + +// TCP ¼­¹ö Á¢¼Ó +static void tcp_client_connect(void) +{ + struct tcp_pcb *pcb; + err_t err = 0; + + pcb = tcp_new(); + if(pcb != NULL) + { + xil_printf("TCP Client: tcp_new() ok.\n"); + ip_set_option(pcb, SOF_REUSEADDR); // sockoption ip, port Àç»ç¿ë ¿É¼Ç Ãß°¡ + err = tcp_bind(pcb, IP_ADDR_ANY, TCP_CLIENT_MY_PORT); + g_stTcpClientMy.cIsConnecting = TRUE; + if(err == (err_t)ERR_OK) + { + xil_printf("TCP Client: binding ok.\n"); + xil_printf("connecting to Server..\n"); + + (void)tcp_connect(pcb, &g_ipaddrMP, TCP_MP_PORT, tcp_client_connected); + } + else + { +#if DEBUG_COVER + xil_printf("TCP Client: bind error.\n"); +#endif + } + } + else + { +#if DEBUG_COVER + xil_printf("TCP Client: Error creating PCB.\n"); +#endif + } +} + +// TCP ¼­¹ö ¹Ýº¹ Á¢¼Ó °ü¸® +void ConnectToTcpServer(void) +{ + if(g_nTcpCliConCnt > TIMER_SEC1) + { + g_nTcpCliConCnt = 0u; + + if(g_stTcpClientMy.cConnected == FALSE) + { + m_nConDelayCnt++; + + if(m_nConDelayCnt > 5u) // 5ÃÊ °æ°ú ÈÄ Á¢¼Ó ½Ãµµ + { + m_nConDelayCnt = 0u; + if(g_stTcpClientMy.cIsConnecting == TRUE) + { + m_nConnectCnt++; + xil_printf("\n\nConnect Count:%d\n\n", m_nConnectCnt); + + xil_printf("TCP Client: Close Client Socket\n"); + tcp_client_connection_close(g_stTcpClientMy.pcb); + g_stTcpClientMy.cIsConnecting = FALSE; + } + else + { + xil_printf("TCP Client: Start Connecting to Server\n"); + tcp_client_connect(); // TCP ¼­¹ö Á¢¼Ó + } + } + else + { + if(g_stTcpClientMy.cIsConnecting == TRUE) + { + xil_printf("TCP Client: Waiting Connection...%d\n", (u32_t)m_nConDelayCnt); + } + else + { + xil_printf("TCP Client: Stay...%d\n", (u32_t)m_nConDelayCnt); + } + } + } + } +} + +// connect Äݹé ÇÔ¼ö +static err_t tcp_client_connected(void *arg, struct tcp_pcb *tpcb, err_t err) +{ + u32_t i; + err_t ret_err = 0; + u32_t ipaddr; + void* Dummy; + struct tcp_pcb *pPcb = NULL; + + Dummy = arg; + +#if TEST_LOG_ON + xil_printf("tcp_client_connected()\n\r"); +#endif + + if(err == (err_t)ERR_OK) + { + if ((err != (err_t)ERR_OK) || (tpcb == NULL)) { + ret_err = ERR_VAL; + } + + ipaddr = tpcb->remote_ip.addr; + xil_printf("accept() - %d.%d.%d.%d:%05d\r\n", (u32_t)(ipaddr & 0xFFu), (u32_t)((ipaddr >> 8) & 0xFFu), (u32_t)((ipaddr >> 16) & 0xFFu), (u32_t)((ipaddr >> 24) & 0xFFu), (u32_t)tpcb->remote_port); + + tcp_setprio(tpcb, TCP_PRIO_MIN); // set priority + + pPcb = (struct tcp_pcb*)mem_malloc(sizeof(struct tcp_pcb)); + if(pPcb != NULL) + { + pPcb = tpcb; + + tcp_arg((struct tcp_pcb*)tpcb, (void*)pPcb); + tcp_recv((struct tcp_pcb*)tpcb, tcp_client_recv); + tcp_sent((struct tcp_pcb*)tpcb, tcp_client_sent); + tcp_poll((struct tcp_pcb*)tpcb, tcp_client_poll, 1); + + g_stTcpClientMy.cConnected = TRUE; + g_stTcpClientMy.pcb = pPcb; + g_stTcpClientMy.nRecvLen = 0; + g_stTcpClientMy.cRecvFlag = FALSE; + g_stTcpClientMy.cIsConnecting = FALSE; // Á¢¼Ó ½Ãµµ Áß ¿©ºÎ, ÇØÁ¦ + + g_nTcpDisconnectChk = 1; // Á¢¼Ó ÈÄ ÀÓ¹«Ã³¸®S/WÀÇ Heart Beat ¹Ì ¼ö½ÅÀÌ 5ÃÊ ÀÌ»ó À¯ÁöµÇ¸é Á¢¼ÓÇØÁ¦ + + ret_err = (err_t)ERR_OK; + } + else + { + tcp_client_connection_close(tpcb); + ret_err = ERR_MEM; + + } + } + else + { + ret_err = (err_t)ERR_OK; + } + + return ret_err; + +} + +// ¼ö½Å Äݹé ÇÔ¼ö +static err_t tcp_client_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) +{ + err_t ret_err; + u32_t ipaddr; + void* Dummy; + + Dummy = arg; + + if(p == NULL) + { +#if TEST_LOG_ON + xil_printf("tcp_client_recv() - p == NULL\r\n"); +#endif + + ipaddr = tpcb->remote_ip.addr; + xil_printf("tcp_client_recv() - p == NULL() - %d.%d.%d.%d:%05d\r\n", (u32_t)(ipaddr & 0xFFu), (u32_t)((ipaddr >> 8) & 0xFFu), (u32_t)((ipaddr >> 16) & 0xFFu), (u32_t)((ipaddr >> 24) & 0xFFu), (u32_t)tpcb->remote_port); + + tcp_client_connection_close(tpcb); + + ret_err = (err_t)ERR_OK; + } + else if(err != (err_t)ERR_OK) + { +#if TEST_LOG_ON + xil_printf("tcp_client_recv() - ERR\r\n"); +#endif + if(p != NULL) + { + (void)pbuf_free(p); + } + + ret_err = err; + } + else + { + g_stTcpClientMy.cRecvFlag = TRUE; + if(p->len < (u32_t)NUM_RECV_BUF) + { + (void)memcpy((void*)&g_stTcpClientMy.szRecvData[0], (const void*)p->payload, (size_t)p->len); + } + g_stTcpClientMy.nRecvLen = p->len; + + ret_err = (err_t)ERR_OK; + } + + return (err_t)ret_err; +} + +// ACK ¼ö½Å Äݹé ÇÔ¼ö +static err_t tcp_client_sent(void *arg, struct tcp_pcb *tpcb, u16_t len) +{ + u16_t nLenDummy = len; + u32_t ipaddr; + const struct tcp_pcb *pcbDummy = tpcb; + void *Dummy; + + Dummy= arg; + + ipaddr = tpcb->remote_ip.addr; + ipaddr += 1u; + + return (err_t)ERR_OK; +} + +// poll Äݹé ÇÔ¼ö +static err_t tcp_client_poll(void *arg, struct tcp_pcb *tpcb) +{ + err_t ret_err = (err_t)ERR_OK; + u32_t ipaddr; + void *Dummy; + + Dummy= arg; + + ipaddr = tpcb->remote_ip.addr; + ipaddr += 1u; + + LWIP_UNUSED_ARG(arg); + + u8_t i = 0u; + + struct tcp_pcb *pcbDummy = tpcb; + + return (err_t)ret_err; +} + +// client socket Á¾·á ó¸® +void tcp_client_connection_close(struct tcp_pcb* tpcb) +{ + err_t err; + u32_t ipaddr; + + m_nConDelayCnt = 0u; // ÀçÁ¢¼Ó ÆÇ´Ü Ä«¿îÅÍ ÃʱâÈ­ + g_nBitDetailHBCnt = 0u; + g_nTcpDisconnectChk = 0u; // Á¢¼Ó ÈÄ ÀÓ¹«Ã³¸®S/WÀÇ Heart Beat ¹Ì ¼ö½ÅÀÌ 5ÃÊ ÀÌ»ó À¯ÁöµÇ¸é Á¢¼ÓÇØÁ¦ + + ipaddr = tpcb->remote_ip.addr; + xil_printf("tcp_client_connection_close() - %d.%d.%d.%d:%05d\r\n", (u32_t)(ipaddr & 0xFFu), (u32_t)((ipaddr >> 8) & 0xFFu), (u32_t)((ipaddr >> 16) & 0xFFu), (u32_t)((ipaddr >> 24) & 0xFFu), (u32_t)tpcb->remote_port); + + g_stTcpClientMy.cConnected = FALSE; + (void)memset((void *)g_stTcpClientMy.szRecvData, (s32_t)0, (s32_t)(NUM_RECV_BUF * sizeof(u8_t))); + g_stTcpClientMy.nRecvLen = 0u; + g_stTcpClientMy.cRecvFlag = FALSE; + g_stTcpClientMy.cIsConnecting = FALSE; + + tcp_arg(tpcb, NULL); // callback ÇØÁ¦ + tcp_recv(tpcb, NULL); + tcp_sent(tpcb, NULL); + tcp_poll(tpcb, NULL, 0u); + + err = tcp_close(tpcb); + if (err != (err_t)ERR_OK) + { + tcp_abort(tpcb); // Free memory with abort + } +} + + + + + + + + + + + + diff --git a/src/tcp_client.h b/src/tcp_client.h new file mode 100644 index 0000000..a1222dd --- /dev/null +++ b/src/tcp_client.h @@ -0,0 +1,45 @@ +#ifndef TCP_CLIENT_H +#define TCP_CLIENT_H + +#include "lwipopts.h" +#include "lwip/ip_addr.h" +#include "lwip/err.h" +#include "lwip/tcp.h" +#include "lwip/inet.h" +#include "xil_printf.h" +#include "eeprom.h" +#include "define.h" +#include "main.h" +#include "ctrl_module.h" + +struct TcpCliConnectPcb +{ + u8_t cConnected; // Á¢¼Ó »óÅ ȮÀÎ, falseÀÏ ¶§ ÀçÁ¢¼Ó ½Ãµµ + struct tcp_pcb *pcb; // tcp_pcb + u8_t szRecvData[NUM_RECV_BUF]; // ¼ö½Å ¹öÆÛ + u32_t nRecvLen; // ¼ö½Å ¹öÆÛ »çÀÌÁî + u8_t cRecvFlag; // ¼ö½Å Ç÷¡±× + u8_t cIsConnecting; // Á¢¼Ó ½Ãµµ Áß ¿©ºÎ +}; + + +struct TcpCliConnectPcb g_stTcpClientMy; // ¼­¹ö Á¢¼Ó¿ë Ŭ¶óÀ̾ðÆ® +static ip_addr_t g_ipaddrMP; // ÀÓ¹«Ã³¸®±â TCP Server IP +static u8_t m_nConDelayCnt; + +static u32_t m_nConnectCnt; +u32_t g_nTcpCliConCnt; // TCP Client°¡ ¼­¹ö¿¡ ¹ÌÁ¢¼Ó »óÅÂÀÏ ¶§ Á¢¼Ó ½Ãµµ¿ë Ä«¿îÅÍ + +u32_t g_nTcpDisconnectCnt; // Á¢¼Ó ÈÄ ÀÓ¹«Ã³¸® S/WÀÇ Heart Beat ¹Ì¼ö½Å 5ÃÊ ÀÌ»ó ¹ß»ý È®Àοë Ä«¿îÅÍ +u32_t g_nTcpDisconnectChk; // Á¢¼Ó ÈÄ ÀÓ¹«Ã³¸®S/WÀÇ Heart Beat ¹Ì ¼ö½ÅÀÌ 5ÃÊ ÀÌ»ó À¯ÁöµÇ¸é Á¢¼ÓÇØÁ¦ + +void InitTcpClient(void); // TCP Client ÃʱâÈ­ +static void tcp_client_connect(void); // TCP ¼­¹ö Á¢¼Ó +void ConnectToTcpServer(void); // TCP ¼­¹ö ¹Ýº¹ Á¢¼Ó °ü¸® +static err_t tcp_client_connected(void *arg, struct tcp_pcb *tpcb, err_t err); // connect Äݹé ÇÔ¼ö +static err_t tcp_client_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err); // ¼ö½Å Äݹé ÇÔ¼ö +static err_t tcp_client_sent(void *arg, struct tcp_pcb *tpcb, u16_t len); // ACK ¼ö½Å Äݹé ÇÔ¼ö +static err_t tcp_client_poll(void *arg, struct tcp_pcb *tpcb); // poll Äݹé ÇÔ¼ö +void tcp_client_connection_close(struct tcp_pcb* tpcb); // client socket Á¾·á ó¸® + +#endif diff --git a/src/tcpipcomm.c b/src/tcpipcomm.c new file mode 100644 index 0000000..0670dd6 --- /dev/null +++ b/src/tcpipcomm.c @@ -0,0 +1,290 @@ +#include "tcpipcomm.h" +#include "ctrl_module.h" + + +// ¹®ÀÚ¿­ ºñ±³(strncmp¿¡¼­ null ¹®ÀÚ ½Ã Á¾·áµÇ´Â ºÎºÐ ºñÈ°¼º) +static u8_t strCompare(const u8_t *str1, const u8_t *str2, u8_t str2Len) +{ + u8_t i, cVal = 1; + + if(str2Len < 10u) + { + for(i = 0u ; i < str2Len ; i++) + { + if(str1[i] != str2[i]) + { + cVal = 0; // ºÒÀÏÄ¡ ÆÇÁ¤ + } + } + } + + return cVal; // ÀÏÄ¡ +} + +// ¹®ÀÚ¿­ ºñ±³ ÃʱâÈ­ ¿î¿ë󸮱â À¯È¿ÇÑ ÆÐŶ ½Äº° +void InitCompareMember(void) +{ + szCase[0][0] = IDC_CMD_TYPE_DEVICE_PBIT; szCase[0][1] = 0x20u; szCase[0][2] = 0x40u; // DevicePBIT_Request PBIT ¿äû + szCase[1][0] = IDC_CMD_TYPE_BIT_DETAIL; szCase[1][1] = 0x20u; szCase[1][2] = 0x40u; // DeviceBITdetail_Request ÀåÄ¡º° ¼¼ºÎ BIT ¿äû + szCase[2][0] = IDC_CMD_TYPE_MAST_CONTROL; szCase[2][1] = 0x23u; szCase[2][2] = 0x40u; // AntMastControl_Request ¾ÈÅ׳ª¸¶½ºÆ® ¼³Á¤ ¹× Á¦¾î ¿äû + szCase[3][0] = IDC_CMD_TYPE_DEVICE_ERASE; szCase[3][1] = 0x20u; szCase[3][2] = 0x40u; // DeviceErase_Request ÀåÄ¡º° ¼Ò°Å ¿äû + szCase[4][0] = IDC_CMD_TYPE_DEVICE_POWER; szCase[4][1] = 0x21u; szCase[4][2] = 0x40u; // DevicePower_Request ÀåÄ¡º° Àü¿øÂ÷´Ü ¿äû + szCase[5][0] = 0xFFu; szCase[5][1] = 0xFEu; szCase[5][2] = 0x40u; // SimAlarm_Set °¡»ó ¾Ë¸² ¼³Á¤ + szCase[6][0] = 0xFFu; szCase[6][1] = 0xFDu; szCase[6][2] = 0x40u; // MastOrigin_Set °¡»ó ¾Ë¸² ¼³Á¤ + +} + +// TCP Client ¼ö½Å ¹× ¼Û½Å ó¸® +void TcpClientCommProceess(void) +{ + u32_t j, nLen = 0; + + if((g_stTcpClientMy.cConnected == TRUE) && (g_stTcpClientMy.cRecvFlag == TRUE)) // Á¢¼ÓµÈ pcb¿Í ¼ö½Å ÆÐŶ Á¸Àç ¿©ºÎ È®ÀÎ + { + g_stTcpClientMy.cRecvFlag = FALSE; // ¼ö½Å Ç÷¡±× ÇØÁ¦ + +#if TEST_LOG_ON + + xil_printf("rec msg:"); + for(j = 0 ; j < g_stTcpClientMy.nRecvLen ; j++) + { + xil_printf("%02X", (u32_t)g_stTcpClientMy.szRecvData[j]); + } + xil_printf(" [%d]\r\n", g_stTcpClientMy.nRecvLen); +#endif + + while(g_stTcpClientMy.nRecvLen >= (u32_t)MIN_TCP_SER_RCV_LEN) // ¿Ï¼ºµÈ ÆÐŶ ÃÖ¼Ò »çÀÌÁ´Ù Å©°Å³ª °°À» °æ¿ì ¼ö½Å ó¸® + { + if(strCompare((const u8_t*)szCase[0], (const u8_t*)g_stTcpClientMy.szRecvData, (u8_t)LEN_COMPARE) == 1u) // 01. DevicePBIT_Request ÀåÄ¡º° PBIT ¿äû + { + nLen = LEN_DEVICE_PBIT_REQ; + g_cMastPeriodSendCmd = TCP_CMD_PERIOD_REPORT_START; // 1ȸ ¼ö½Å ½Ã Àü¼Û ½ÃÀÛ(Àü¼Û ÁßÁö ¾øÀ½) + + FuncAntMastPBITRes((const u8_t *)g_stTcpClientMy.szRecvData); // 01. AntMastPBIT_Response ÀÀ´ä ó¸® + } + else if(strCompare((const u8_t*)szCase[1], (const u8_t*)g_stTcpClientMy.szRecvData, (u8_t)LEN_COMPARE) == 1u) // 02. DeviceBITdetail_Request ÀåÄ¡º° ¼¼ºÎ BIT ¿äû + { + nLen = LEN_DEVICE_BIT_DETAIL_REQ; + + if((g_stTcpClientMy.szRecvData[11] == 0x40u) && (g_stTcpClientMy.szRecvData[12] == 0x00u)) // ÀåÄ¡ È®ÀÎ 0x0040(B/E) ¡æ 0x4000(L/E) Device(2Byte) 0x0040(Bit6 High) + { + FuncAntMastBITdetailRes((const u8_t *)g_stTcpClientMy.szRecvData); // 02. AntMastBITdetail_Response ÀÀ´ä ó¸® + } + } + else if(strCompare((const u8_t*)szCase[2], (const u8_t*)g_stTcpClientMy.szRecvData, (u8_t)LEN_COMPARE) == 1u) // 03. AntMastControl_Request ¾ÈÅ׳ª¸¶½ºÆ® ¼³Á¤ ¹× Á¦¾î ¿äû + { + nLen = LEN_ANT_MAST_CONTROL_REQ; + + g_cOverCurrFlag = 0u; + + g_cMastRcvCmd = g_stTcpClientMy.szRecvData[10]; // Control(1) 0x11: »ç¿ëÀÚ ÀÔ·Â, 0x10: ¿¬¼Ó »ó½Â, 0x01: ¿¬¼Ó ÇÏ°­, 0x00: ÁßÁö + + if(g_cMastRcvCmd == (u8_t)CMD_MOTOR_USER_INPUT) // À¯Àú ÀԷ°ªÀÌ ÀÖ´Â °æ¿ì + { + nLen += (u32_t)4; // ¼ö½Å±æÀÌ Áõ°¡ + g_nSetMastHeight = (u32_t)g_stTcpClientMy.szRecvData[14] << 24; // Little Endian À» Big Endian·Î + g_nSetMastHeight += (u32_t)g_stTcpClientMy.szRecvData[13] << 16; + g_nSetMastHeight += (u32_t)g_stTcpClientMy.szRecvData[12] << 8; + g_nSetMastHeight += g_stTcpClientMy.szRecvData[11]; // ¸ñÇ¥ ³ôÀÌ°ª Àû¿ë +#if DEBUG_CTRL_MODULE + xil_printf("g_nSetMastHeight:%d\r\n", (u32_t)g_nSetMastHeight); +#endif + } + else + { + g_nSetMastHeight = 0; + } + + SetMotor(g_cMastRcvCmd); // Motor Up/Down/Stop ±¸µ¿ Á¦¾î + + FuncAntMastControlRes((const u8_t *)g_stTcpClientMy.szRecvData); // 03. AntMastControl_Response ÀÀ´ä ó¸® + } + else if(strCompare((const u8_t*)szCase[4], (const u8_t*)g_stTcpClientMy.szRecvData, (u8_t)LEN_COMPARE) == 1u) // 05. DevicePower_Request ÀåÄ¡º° Àü¿øÂ÷´Ü ¿äû + { + nLen = LEN_DEVICE_POWER_REQ; + + if(g_stTcpClientMy.szRecvData[11] == 0xA0u) // Unit È®ÀÎ, 0xA0:¾ÈÅ׳ª¸¶½ºÆ® + { + FuncAntMastPowerRes((const u8_t *)g_stTcpClientMy.szRecvData); // 05. AntMastPower_Response ÀÀ´ä ó¸® + } + } + else + { + g_stTcpClientMy.nRecvLen = 0; // while loop ºüÁ®³ª°¡±â À§ÇÑ Ã³¸® + } + + if(nLen > 0u) + { + g_stTcpClientMy.nRecvLen -= nLen; // »ç¿ëÇÑ ±æÀÌ Á¦°Å + (void)memcpy((void*)&g_stTcpClientMy.szRecvData[0], (const void*)(&g_stTcpClientMy.szRecvData[nLen]), (size_t)g_stTcpClientMy.nRecvLen); // »ç¿ëÇÑ ÆÐŶ Á¦°Å + } + nLen = 0; + } + + (void)memset((void *)g_stTcpClientMy.szRecvData, (s32_t)0, (s32_t)NUM_RECV_BUF); // ³²Àº ÆÐŶÀÌ ÀÖ´Ù¸é Á¦°Å + g_stTcpClientMy.nRecvLen = 0; + } +} + +// 01.AntMastPBIT_Response ÀÀ´ä ó¸® +static void FuncAntMastPBITRes(const uint8_t *pszData) +{ + u32_t i = 0, j; + u8_t szBuf[LEN_DEVICE_PBIT_REQ + 2 + ARR_BUF_MARGIN]; + u8_t cData = 0; + + (void)memset((void *)szBuf, (s32_t)0, (s32_t)(sizeof(szBuf))); + + szBuf[i++] = IDC_CMD_TYPE_DEVICE_PBIT; // Type + szBuf[i++] = 0x35u; // ID + szBuf[i++] = ICD_CMD_UNIT_MP; // Sour + szBuf[i++] = ICD_CMD_UNIT_MAST; // Dest + szBuf[i++] = (u8_t)g_cSn; // SN + g_cSn += (u8_t)1; + szBuf[i++] = ICD_CMD_TM_TCP; // TM + szBuf[i++] = 0x02u; // Length + szBuf[i++] = 0x00u; // Length + szBuf[i++] = 0x00u; // Length + szBuf[i++] = 0x00u; // Length + + if(g_cEncoderErrFlag == 1u) // ¿£ÄÚ´õ »óÅ + { + szBuf[i++] = 0x0Au; // Function ¾ÈÅ׳ª¸¶½ºÆ® È®Àå/¼öÃà 0x02, ¿î¿ëÂüÁ¶ 0x08 = 00001010b = 0x0A + szBuf[i++] = 0x05u; // Device ¾ÈÅ׳ª¸¶½ºÆ® Bit0: 1, Åë½Å Bit1: 0, ÇϺÎÂüÁ¶ Bit2: 1 = 0x05 + } + else + { + szBuf[i++] = 0x00u; + szBuf[i++] = 0x00u; + } + + struct pbuf *p = NULL; + p = pbuf_alloc(PBUF_TRANSPORT, (u16_t)i, PBUF_POOL); + if(p != NULL) + { + p->payload = szBuf; + p->len = (u16_t)i; + (void)tcp_write((struct tcp_pcb*)g_stTcpClientMy.pcb, (const void*)p->payload, (u16_t)p->len, (u8_t)1); + (void)pbuf_free(p); + } + szBuf[0] = pszData[0]; +} + +// 02.AntMastBITdetail_Response ÀÀ´ä ó¸® +static void FuncAntMastBITdetailRes(const uint8_t *pszData) +{ + u32_t i = 0, j; + u8_t szBuf[LEN_DEVICE_BIT_DETAIL_REQ + 1 + ARR_BUF_MARGIN]; + + (void)memset((void *)szBuf, (s32_t)0, (s32_t)(sizeof(szBuf))); + + szBuf[i++] = IDC_CMD_TYPE_BIT_DETAIL; // Type + szBuf[i++] = 0x35u; // ID + szBuf[i++] = ICD_CMD_UNIT_MP; // Sour + szBuf[i++] = ICD_CMD_UNIT_MAST; // Dest + szBuf[i++] = (u8_t)g_cSn; // SN + g_cSn += (u8_t)1; + szBuf[i++] = ICD_CMD_TM_TCP; // TM + szBuf[i++] = 0x02u; // Length + szBuf[i++] = 0x00u; // Length + szBuf[i++] = 0x00u; // Length + szBuf[i++] = 0x00u; // Length + + szBuf[i++] = pszData[10]; // 0x00(PBIT), 0x40(CBIT) + + szBuf[i++] = g_cBitDetail; // BIT Detail Bit 3 : ¸ðÅÍ°úÀü·ù Bit 2 : ³ôÀÌ°ª Ç¥½Ã¿ë ¿£ÄÚ´õ üũ, Bit 1 : ¸¶½ºÆ® ±¸µ¿ üũ, Bit 0 : ¾ÈÅ׳ª¸¶½ºÆ®-ÀÓ¹«ÅëÁ¦±â Åë½Å ¼ö½Å ¹Ì¹ß»ý(0)/¹ß»ý(1) + + struct pbuf *p = NULL; + p = pbuf_alloc(PBUF_TRANSPORT, (u16_t)i, PBUF_POOL); + if(p != NULL) + { + p->payload = szBuf; + p->len = (u16_t)i; + (void)tcp_write((struct tcp_pcb*)g_stTcpClientMy.pcb, (const void*)p->payload, (u16_t)p->len, (u8_t)1); + (void)pbuf_free(p); + } + szBuf[0] = pszData[0]; +} + +// 03.AntMastControl_Response ÀÀ´ä ó¸® +static void FuncAntMastControlRes(const uint8_t *pszData) +{ + u32_t i = 0, j; + u8_t szBuf[LEN_ANT_MAST_CONTROL_REQ + 4 + ARR_BUF_MARGIN]; + + (void)memset((void *)szBuf, (s32_t)0, (s32_t)(sizeof(szBuf))); + + szBuf[i++] = IDC_CMD_TYPE_MAST_CONTROL; // Type + szBuf[i++] = 0x33u; // ID + szBuf[i++] = ICD_CMD_UNIT_MP; // Sour + szBuf[i++] = ICD_CMD_UNIT_MAST; // Dest + szBuf[i++] = (u8_t)g_cSn; // SN + g_cSn += (u8_t)1; + szBuf[i++] = ICD_CMD_TM_TCP; // TM + if(g_cMastRcvCmd != (u8_t)CMD_MOTOR_USER_INPUT) // À¯Àú ÀԷ°ªÀÌ ¾ø´Â °æ¿ì + { + szBuf[i++] = 0x01u; // Length + szBuf[i++] = 0x00u; // Length + szBuf[i++] = 0x00u; // Length + szBuf[i++] = 0x00u; // Length + szBuf[i++] = g_cMastRcvCmd; // Control(1) 0xC0: »ç¿ëÀÚ ÀÔ·Â, 0x80: ¿¬¼Ó »ó½Â, 0x40: ¿¬¼Ó ÇÏ°­, 0x00: ÁßÁö + } + else + { + szBuf[i++] = 0x05u; // Length + szBuf[i++] = 0x00u; // Length + szBuf[i++] = 0x00u; // Length + szBuf[i++] = 0x00u; // Length + szBuf[i++] = g_cMastRcvCmd; // Control(1) 0xC0: »ç¿ëÀÚ ÀÔ·Â, 0x80: ¿¬¼Ó »ó½Â, 0x40: ¿¬¼Ó ÇÏ°­, 0x00: ÁßÁö + + szBuf[i++] = (u8_t)g_nSetMastHeight & 0xFFu; // Little Endian ó¸®, ¼³Á¤ ³ôÀÌ°ª ÀÔ·Â + szBuf[i++] = (u8_t)(g_nSetMastHeight >> 8) & 0xFFu; + szBuf[i++] = (u8_t)(g_nSetMastHeight >> 16) & 0xFFu; + szBuf[i++] = (u8_t)(g_nSetMastHeight >> 24) & 0xFFu; + } + + struct pbuf *p = NULL; + p = pbuf_alloc(PBUF_TRANSPORT, (u16_t)i, PBUF_POOL); + /* MISRA C Dir 4.11 : ¼Û½Å ¹öÆÛ À¯È¿¼º °Ë»ç*/ + if(p != NULL) + { + p->payload = szBuf; + p->len = (u16_t)i; + (void)tcp_write((struct tcp_pcb*)g_stTcpClientMy.pcb, (const void*)p->payload, (u16_t)p->len, (u8_t)1); + (void)pbuf_free(p); + } + szBuf[0] = pszData[0]; +} + +// 05. AntMastPower_Response ÀÀ´ä ó¸® +static void FuncAntMastPowerRes(const uint8_t *pszData) +{ + u32_t i = 0, j; + u8_t szBuf[LEN_DEVICE_POWER_REQ + ARR_BUF_MARGIN]; + + (void)memset((void *)szBuf, (s32_t)0, (s32_t)(sizeof(szBuf))); + + szBuf[i++] = IDC_CMD_TYPE_DEVICE_POWER; // Type + szBuf[i++] = 0x31u; // ID + szBuf[i++] = ICD_CMD_UNIT_MP; // Sour + szBuf[i++] = ICD_CMD_UNIT_MAST; // Dest + szBuf[i++] = (u8_t)g_cSn; // SN + g_cSn += (u8_t)1; + szBuf[i++] = ICD_CMD_TM_TCP; // TM + szBuf[i++] = 0x01u; // Length + szBuf[i++] = 0x00u; // Length + szBuf[i++] = 0x00u; // Length + szBuf[i++] = 0x00u; // Length + szBuf[i++] = pszData[10]; // Control 1Byte + + struct pbuf *p = NULL; + p = pbuf_alloc(PBUF_TRANSPORT, (u16_t)i, PBUF_POOL); + if(p != NULL) + { + p->payload = (void*)szBuf; + p->len = (u16_t)i; + (void)tcp_write((struct tcp_pcb*)g_stTcpClientMy.pcb, (const void*)p->payload, (u16_t)p->len, (u8_t)1u); + (void)pbuf_free(p); + } + szBuf[0] = pszData[0]; +} diff --git a/src/tcpipcomm.h b/src/tcpipcomm.h new file mode 100644 index 0000000..1a6397f --- /dev/null +++ b/src/tcpipcomm.h @@ -0,0 +1,21 @@ +#ifndef TCPIP_COMM_H +#define TCPIP_COMM_H + +#include "define.h" +#include "tcp_client.h" + + +static u8_t g_cSn; // ÀÀ´äÆÐŶ ¼Û½Å Ä«¿îÅÍ +u8_t szCase[7][3]; // ¹®ÀÚ¿­ ºñ±³ ¹è¿­ + +static u8_t strCompare(const uint8_t *str1, const uint8_t *str2, uint8_t str2Len); // ¹®ÀÚ¿­ ºñ±³(strncmp¿¡¼­ null ¹®ÀÚ ½Ã Á¾·áµÇ´Â ºÎºÐ ºñÈ°¼º) +void InitCompareMember(void); // ¹®ÀÚ¿­ ºñ±³ ÃʱâÈ­ +void TcpClientCommProceess(void); // TCP Client ¼ö½Å ¹× ¼Û½Å ó¸® + +// TCP ¼­¹öÀÇ Client ÀÀ´ä +static void FuncAntMastPBITRes(const uint8_t *pszData); // 01. AntMastPBIT_Response ÀÀ´ä ó¸® +static void FuncAntMastBITdetailRes(const uint8_t *pszData); // 02. AntMastBITdetail_Response ÀÀ´ä ó¸® +static void FuncAntMastControlRes(const uint8_t *pszData); // 03. AntMastControl_Response ÀÀ´ä ó¸® +static void FuncAntMastPowerRes(const uint8_t *pszData); // 05. AntMastPower_Response ÀÀ´ä ó¸® + +#endif // TCPIP_COMM_H diff --git a/src/udp_client.c b/src/udp_client.c new file mode 100644 index 0000000..cf220eb --- /dev/null +++ b/src/udp_client.c @@ -0,0 +1,293 @@ +#include "udp_client.h" + +// UDP Server ÃʱâÈ­ +void InitUdpServer(void) +{ + s8_t err; + ip_addr_t addr; + + + InitUdpClientMember(); // UDP Client ±¸Á¶Ã¼ ÃʱâÈ­ + + /* Create Client PCB */ + g_stUdpCliPcb.pcb = udp_new(); + if(g_stUdpCliPcb.pcb != NULL) + { + err = udp_bind(g_stUdpCliPcb.pcb, IP_ADDR_ANY, UDP_MY_PORT); + + if(err == (s8_t)ERR_OK) + { + xil_printf("udp server binding ok\n"); + udp_recv(g_stUdpCliPcb.pcb, udp_server_receive_callback, NULL); + + IP_ADDR4(&addr, UDP_SERVER_IP_ADDR1, UDP_SERVER_IP_ADDR2, UDP_SERVER_IP_ADDR3, UDP_SERVER_IP_ADDR4); // ÀÓ¹« IP + g_stUdpCliPcb.pcb->remote_ip.addr = addr.addr; // ¼Û½Åó Á¤º¸ È®ÀÎ + g_stUdpCliPcb.pcb->remote_port = 61202; // 51271 + } + else + { +#if DEBUG_COVER + xil_printf("udp server binding error\n"); +#endif + } + } +} + +static void udp_server_receive_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, ip_addr_t *addr, u16_t port) +{ + uint8_t i; + u8_t szBuff[100]; + void *Dummy; + struct udp_pcb* pDummyPcb; + ip_addr_t* pDummyAddr; + u16_t DummyPort; + + Dummy = arg; + pDummyPcb = upcb; + pDummyAddr = addr; + DummyPort = port; + DummyPort++; + + +#if TEST_LOG_ON_UDP + xil_printf("udp recv:%s:%d\r\n", ip4addr_ntoa((const ip_addr_t *)addr), port); +#endif + + if(p->len < 100u) + { + (void)memcpy((void*)szBuff, (const void*)(p->payload), (size_t)p->len); + + if((szBuff[0] == 0x92u) && (szBuff[1] == 0x10u) && (szBuff[2] == 0x40u) && (szBuff[3] == 0x61u)) // ÀÓ¹«Ã³¸®±â Heart Beat ¼ö½Å ¿©ºÎ °Ë»ç + { + m_cRecvHBFromMP = 1; + + g_nBitDetailHBCnt = 0; // Ä«¿îÅÍ ÃʱâÈ­ + g_cBitDetailHBErr = 0; // Heart Beat ¼ö½Å On ÆÇÁ¤(Á¤»ó) + + g_nTcpDisconnectCnt = 0; // Ä«¿îÅÍ ÃʱâÈ­, Á¢¼Ó ÈÄ ÀÓ¹«Ã³¸® S/WÀÇ Heart Beat ¹Ì¼ö½Å 5ÃÊ ÀÌ»ó ¹ß»ý È®Àοë Ä«¿îÅÍ + g_nTcpDisconnectChk = 1; // Á¢¼Ó À¯Áö, Á¢¼Ó ÈÄ ÀÓ¹«Ã³¸®S/WÀÇ Heart Beat ¹Ì ¼ö½ÅÀÌ 5ÃÊ ÀÌ»ó À¯ÁöµÇ¸é Á¢¼ÓÇØÁ¦ + } + } + + (void)pbuf_free(p); /* Free the p buffer */ +} + +// UDP Client ±¸Á¶Ã¼ ÃʱâÈ­ +static void InitUdpClientMember(void) +{ + m_cRecvHBFromMP = 1; + g_cBitDetailHBErr = 0; + + g_unUdpServerPort = UDP_SERVER_PORT; + + g_stUdpCliPcb.nRecvLen = 0; + (void)memset((void*)g_stUdpCliPcb.szRecvData, (s32_t)0, (size_t)(NUM_RECV_BUF * sizeof(u8_t))); + g_stUdpCliPcb.cRecvFlag = FALSE; +} + +// UDP Åë½Å ó¸® +void UdpCommProcess(void) +{ + UdpCommPeriod(); // UDP ÁÖ±âÀûÀÎ Åë½Å ó¸® + + if(g_nBitDetailHBCnt > TIMER_SEC3) + { + g_nBitDetailHBCnt = 0; // Ä«¿îÅÍ ÃʱâÈ­ + g_cBitDetailHBErr = 1; // Heart Beat ¼ö½Å ¿À·ù ÆÇÁ¤ + } + if(g_nTcpDisconnectCnt > TIMER_SEC10) + { + g_nTcpDisconnectCnt = 0; + g_nTcpDisconnectChk = 0; // Á¢¼Ó ÇØÁ¦, Á¢¼Ó ÈÄ ÀÓ¹«Ã³¸®S/WÀÇ Heart Beat ¹Ì ¼ö½ÅÀÌ 5ÃÊ ÀÌ»ó À¯ÁöµÇ¸é Á¢¼ÓÇØÁ¦ + + if(g_stTcpClientMy.cConnected == TRUE) + { + tcp_client_connection_close(g_stTcpClientMy.pcb); + } + } +} + +// UDP ÁÖ±âÀûÀÎ Åë½Å ó¸® +static void UdpCommPeriod(void) +{ + if(g_nReportCnt > TIMER_MSEC333) // main() - makeTiming() + { + g_nReportCnt = 0u; + + if(m_cReportIdx == 0u) + { + m_cReportIdx++; + if(m_cRecvHBFromMP == 1u) // ÀÓ¹«Ã³¸®±â Heart Beat ¼ö½ÅµÇ¸é ÀÀ´ä ½ÃÀÛ + { + if(g_cMastPeriodSendCmd == TCP_CMD_PERIOD_REPORT_START) + { + FuncAntMastStatusReport(); // ¾ÈÅ׳ª ¸¶½ºÆ® »óÅ º¸°í ¼Û½Å + } + } + } + else if(m_cReportIdx == 1u) + { + m_cReportIdx++; + if(m_cRecvHBFromMP == 1u) // ÀÓ¹«Ã³¸®±â Heart Beat ¼ö½ÅµÇ¸é ÀÀ´ä ½ÃÀÛ + { + if(g_cMastPeriodSendCmd == TCP_CMD_PERIOD_REPORT_START) + { + FuncAntMastCBitReport(); // ¾ÈÅ׳ª ¸¶½ºÆ® CBIT º¸°í ¼Û½Å + } + } + } + else// if(m_cReportIdx == 2u) // Àü¿ø °ø±Þ ½Ã »ó½Ã Àü¼Û + { + m_cReportIdx = 0u; + FuncHeartBeatData(); // LAN ¿¬°á¼º È®ÀÎ µ¥ÀÌÅÍ + } + } +} + +// ¾ÈÅ׳ª ¸¶½ºÆ® »óÅ º¸°í ¼Û½Å +static void FuncAntMastStatusReport(void) +{ + u32_t i = 0; + u8_t szBuf[LEN_ANT_MAST_STATUS_REPORT + ARR_BUF_MARGIN]; + struct pbuf *p = NULL; + + (void)memset((void*)szBuf, (s32_t)0, (size_t)(sizeof(szBuf))); + + szBuf[i++] = IDC_CMD_TYPE_STATUS_REPORT; // Type + szBuf[i++] = 0x04u; // ID + szBuf[i++] = ICD_CMD_UNIT_MP; // Sour + szBuf[i++] = ICD_CMD_UNIT_MAST; // Dest + szBuf[i++] = (u8_t)g_cSn; // SN + g_cSn += (u8_t)1; + szBuf[i++] = IDC_CMD_TM_UDP; // TM + szBuf[i++] = 0x05u; // Length + szBuf[i++] = 0x00u; // Length + szBuf[i++] = 0x00u; // Length + szBuf[i++] = 0x00u; // Length + + if(g_cMastRcvCmd == 0x00u) + { + szBuf[i++] = 0x00u; // ¾ÈÅ׳ª¸¶½ºÆ® ´ë±â Áß + } + else + { + szBuf[i++] = 0x40u; // ¾ÈÅ׳ª¸¶½ºÆ® µ¿ÀÛ Áß + } + + szBuf[i++] = (u8_t)g_nMastCurrHeight & 0xFFu; // ÇöÀç ³ôÀÌ°ª ÀÔ·Â + szBuf[i++] = (u8_t)(g_nMastCurrHeight >> 8) & 0xFFu; // ÇöÀç ³ôÀÌ°ª ÀÔ·Â + szBuf[i++] = (u8_t)(g_nMastCurrHeight >> 16) & 0xFFu; // ÇöÀç ³ôÀÌ°ª ÀÔ·Â + szBuf[i++] = (u8_t)(g_nMastCurrHeight >> 24) & 0xFFu; // ÇöÀç ³ôÀÌ°ª ÀÔ·Â + + p = pbuf_alloc(PBUF_TRANSPORT, (u16_t)i, PBUF_POOL); + if(p != NULL) + { + (void)pbuf_take((struct pbuf*)p, (const void*)(u8_t*)szBuf, (u16_t)i); + (void)udp_sendto((struct udp_pcb*)g_stUdpCliPcb.pcb, (struct pbuf*)p, (const ip_addr_t*)&g_stUdpCliPcb.pcb->remote_ip, (u16_t)g_stUdpCliPcb.pcb->remote_port); + (void)pbuf_free(p); + } + else + { +#if DEBUG_COVER + xil_printf("error allocating pbuf to send\r\n"); +#endif + } +} + +// ¾ÈÅ׳ª ¸¶½ºÆ® CBIT º¸°í ¼Û½Å +static void FuncAntMastCBitReport(void) +{ + u32_t i = 0; + u8_t szBuf[LEN_ANT_MAST_CBIT_REPORT + ARR_BUF_MARGIN]; + u8_t cData = 0; + struct pbuf *p = NULL; + + (void)memset((void*)szBuf, (s32_t)0, (size_t)(sizeof(szBuf))); + + szBuf[i++] = IDC_CMD_TYPE_CBIT_REPORT; // Type + szBuf[i++] = 0x05u; // ID + szBuf[i++] = ICD_CMD_UNIT_MP; // Sour + szBuf[i++] = ICD_CMD_UNIT_MAST; // Dest + szBuf[i++] = (u8_t)g_cSn; // SN + g_cSn += (u8_t)1; + szBuf[i++] = IDC_CMD_TM_UDP; // TM + szBuf[i++] = 0x02u; // Length + szBuf[i++] = 0x00u; // Length + szBuf[i++] = 0x00u; // Length + szBuf[i++] = 0x00u; // Length + + if((g_cBitDetailHBErr == 1u) || (g_cEncoderErrFlag == 1u)) // ÃÖ¿ì¼± Á¶°Ç: Åë½Å ¿¡·¯ ¶Ç´Â ¿£ÄÚ´õ ¿¡·¯ + { + szBuf[i++] = 0x0Au; // Function ¾ÈÅ׳ª¸¶½ºÆ® È®Àå/¼öÃà 0x02, ¿î¿ëÂüÁ¶ 0x08 = 00001010b = 0x0A + + if(g_cBitDetailHBErr == 1u) // Åë½Å ¿¡·¯ + { + szBuf[i++] = 0x07u; // Device ¾ÈÅ׳ª¸¶½ºÆ® Bit0: 1, Åë½Å Bit1: 1, ÇϺÎÂüÁ¶ Bit2: 1 = 0x05 + } + else + { + szBuf[i++] = 0x05u; // Device ¾ÈÅ׳ª¸¶½ºÆ® Bit0: 1, Åë½Å Bit1: 0, ÇϺÎÂüÁ¶ Bit2: 1 = 0x05 + } + } + else if(g_cOverCurrFlag == 1u) + { + szBuf[i++] = 0x05u; // Function ¾ÈÅ׳ª¸¶½ºÆ® È®Àå/¼öÃà 0x02, ¿î¿ëÂüÁ¶ 0x08 = 00001010b = 0x0A + szBuf[i++] = 0x05u; // Device ¾ÈÅ׳ª¸¶½ºÆ® Bit0: 1, Åë½Å Bit1: 0, ÇϺÎÂüÁ¶ Bit2: 1 = 0x05 + } + else + { + szBuf[i++] = 0x00u; + szBuf[i++] = 0x00u; + } + + p = pbuf_alloc(PBUF_TRANSPORT, (u16_t)i, PBUF_POOL); + if(p != NULL) + { + (void)pbuf_take((struct pbuf*)p, (const void*)(u8_t*)szBuf, (u16_t)i); + (void)udp_sendto((struct udp_pcb*)g_stUdpCliPcb.pcb, (struct pbuf*)p, (const ip_addr_t*)&g_stUdpCliPcb.pcb->remote_ip, (u16_t)g_stUdpCliPcb.pcb->remote_port); + (void)pbuf_free(p); + } + else + { +#if DEBUG_COVER + xil_printf("error allocating pbuf to send\r\n"); +#endif + } +} + +// LAN ¿¬°á¼º È®ÀÎ µ¥ÀÌÅÍ +static void FuncHeartBeatData(void) +{ + u32_t i = 0; + u8_t szBuf[LEN_HEART_BEAT_DATA + ARR_BUF_MARGIN]; + struct pbuf *p = NULL; + + (void)memset((void*)szBuf, (s32_t)0, (size_t)(sizeof(szBuf))); + + szBuf[i++] = IDC_CMD_TYPE_HEART_BEAT; // Type + szBuf[i++] = 0x10u; // ID + szBuf[i++] = ICD_CMD_UNIT_MP; // Sour + szBuf[i++] = ICD_CMD_UNIT_MAST; // Dest + szBuf[i++] = (u8_t)g_cSn; // SN + g_cSn += (u8_t)1; + szBuf[i++] = IDC_CMD_TM_UDP; // TM + szBuf[i++] = 0x01u; // Length + szBuf[i++] = 0x00u; // Length + szBuf[i++] = 0x00u; // Length + szBuf[i++] = 0x00u; // Length + szBuf[i++] = 0x00u; // Reserved + + p = pbuf_alloc(PBUF_TRANSPORT, (u16_t)i, PBUF_POOL); + if(p != NULL) + { + (void)pbuf_take((struct pbuf*)p, (const void*)(u8_t*)szBuf, (u16_t)i); + (void)udp_sendto((struct udp_pcb*)g_stUdpCliPcb.pcb, (struct pbuf*)p, (const ip_addr_t*)&g_stUdpCliPcb.pcb->remote_ip, (u16_t)g_stUdpCliPcb.pcb->remote_port); + (void)pbuf_free(p); + } + else + { +#if DEBUG_COVER + xil_printf("error allocating pbuf to send\r\n"); +#endif + } +} diff --git a/src/udp_client.h b/src/udp_client.h new file mode 100644 index 0000000..9cc593d --- /dev/null +++ b/src/udp_client.h @@ -0,0 +1,46 @@ +#ifndef UDP_CLIENT_H +#define UDP_CLIENT_H + +#include "lwipopts.h" +#include "xlwipconfig.h" +#include "lwip/ip_addr.h" +#include "lwip/err.h" +#include "lwip/udp.h" +#include "lwip/inet.h" +#include "xil_printf.h" +#include "platform.h" +#include +#include "ctrl_module.h" +#include "tcpipcomm.h" + +#include "define.h" + +struct ClientUdpPcb +{ + struct udp_pcb *pcb; // udp_pcb + u8_t szRecvData[NUM_RECV_BUF]; // ¼ö½Å ¹öÆÛ + u32_t nRecvLen; // ¼ö½Å ¹öÆÛ »çÀÌÁî + u8_t cRecvFlag; // ¼ö½Å Ç÷¡±× +} ; + +static struct ClientUdpPcb g_stUdpCliPcb; // UDP¼­¹ö¿¡ Á¢¼ÓÇϴ Ŭ¶óÀ̾ðÆ® ó¸® + +u32_t g_nReportCnt; // udp_client¿¡¼­ »ç¿ë, static ¼±¾ðÇÏ¸é ¾ÈµÊ + +static u16_t g_unUdpServerPort; // UDP Server Port +static u8_t m_cReportIdx = 0; // Report 2°³ ±³Â÷ ¼Û½Å¿ë +static u8_t m_cRecvHBFromMP = 0; // ÀÓ¹«Ã³¸®±â·ÎºÎÅÍ Heart Beat ¼ö½Å ¿©ºÎ + + +void InitUdpServer(void); +static void udp_server_receive_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, ip_addr_t *addr, u16_t port); + +static void InitUdpClientMember(void); // UDP Client ±¸Á¶Ã¼ ÃʱâÈ­ +void UdpCommProcess(void); // UDP Åë½Å ó¸® +static void UdpCommPeriod(void); // UDP ÁÖ±âÀûÀÎ Åë½Å ó¸® + +static void FuncAntMastStatusReport(void); // ¾ÈÅ׳ª ¸¶½ºÆ® »óÅ º¸°í ¼Û½Å +static void FuncAntMastCBitReport(void); // ¾ÈÅ׳ª ¸¶½ºÆ® CBIT º¸°í ¼Û½Å +static void FuncHeartBeatData(void); // LAN ¿¬°á¼º È®ÀÎ µ¥ÀÌÅÍ + +#endif // UDP_CLIENT_H