update
This commit is contained in:
parent
70a4f70825
commit
16a51a4912
2
src/Xilinx.spec
Normal file
2
src/Xilinx.spec
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*startfile:
|
||||||
|
crti%O%s crtbegin%O%s
|
474
src/ctrl_module.c
Normal file
474
src/ctrl_module.c
Normal file
@ -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); // 엔코더 멀티턴값 쓰기
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
58
src/ctrl_module.h
Normal file
58
src/ctrl_module.h
Normal file
@ -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
|
230
src/define.h
Normal file
230
src/define.h
Normal file
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
200
src/eeprom.c
Normal file
200
src/eeprom.c
Normal file
@ -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; // 값 가져가기
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
19
src/eeprom.h
Normal file
19
src/eeprom.h
Normal file
@ -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
|
289
src/lscript.ld
Normal file
289
src/lscript.ld
Normal file
@ -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 = .;
|
||||||
|
}
|
||||||
|
|
277
src/main.c
Normal file
277
src/main.c
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
17
src/main.h
Normal file
17
src/main.h
Normal file
@ -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
|
179
src/platform.c
Normal file
179
src/platform.c
Normal file
@ -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
|
40
src/platform.h
Normal file
40
src/platform.h
Normal file
@ -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
|
10
src/platform_config.h
Normal file
10
src/platform_config.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef __PLATFORM_CONFIG_H_
|
||||||
|
#define __PLATFORM_CONFIG_H_
|
||||||
|
|
||||||
|
|
||||||
|
#define PLATFORM_EMAC_BASEADDR XPAR_XEMACPS_0_BASEADDR
|
||||||
|
|
||||||
|
#define PLATFORM_ZYNQ
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
233
src/platform_zynq.c
Normal file
233
src/platform_zynq.c
Normal file
@ -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.
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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
|
288
src/tcp_client.c
Normal file
288
src/tcp_client.c
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
45
src/tcp_client.h
Normal file
45
src/tcp_client.h
Normal file
@ -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
|
290
src/tcpipcomm.c
Normal file
290
src/tcpipcomm.c
Normal file
@ -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];
|
||||||
|
}
|
21
src/tcpipcomm.h
Normal file
21
src/tcpipcomm.h
Normal file
@ -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
|
293
src/udp_client.c
Normal file
293
src/udp_client.c
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
46
src/udp_client.h
Normal file
46
src/udp_client.h
Normal file
@ -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 <sleep.h>
|
||||||
|
#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
|
Loading…
Reference in New Issue
Block a user